Analisi HTML e Screen Scraping con la semplice libreria HTML HTML

Se hai bisogno di analizzare HTML, le espressioni regolari non sono la strada da percorrere. In questo tutorial, imparerai come utilizzare un parser open source, facilmente appreso, leggere, modificare e sputare HTML da fonti esterne. Usando nettuts come esempio, imparerai come ottenere un elenco di tutti gli articoli pubblicati sul sito e visualizzarli.

A proposito, puoi trovare anche parser su Envato Market, come HTML5 Parser.

Parser HTML5 su mercato Envato

Passaggio 1. Preparazione

La prima cosa che devi fare è scaricare una copia della libreria simpleHTMLdom, disponibile gratuitamente da sourceforge.

Ci sono diversi file nel download, ma l'unico di cui hai bisogno è il file simple_html_dom.php; il resto sono esempi e documentazione.


Passaggio 2. Informazioni di base sull'analisi

Questa libreria è molto facile da usare, ma ci sono alcune nozioni di base da consultare prima di metterlo in pratica.

Caricamento HTML

$ html = new simple_html_dom (); // Carica da una stringa $ html-> carica ('

Ciao mondo!

Erano qui

'); // Carica un file $ html-> load_file ('http://net.tutsplus.com/');

Puoi creare il tuo oggetto iniziale caricando HTML da una stringa o da un file. Il caricamento di un file può essere effettuato tramite URL o tramite il tuo file system locale.

Una nota di cautela: il metodo load_file () delega il suo lavoro ai file_get_contents di PHP. Se allow_url_fopen non è impostato su true nel file php.ini, potresti non essere in grado di aprire un file remoto in questo modo. In questo caso potresti sempre ricorrere alla libreria CURL per caricare le pagine remote, quindi leggerle con il metodo load ().

Accesso alle informazioni

Una volta che hai il tuo oggetto DOM, puoi iniziare a lavorare con esso usando find () e creando collezioni. Una collezione è un gruppo di oggetti trovati tramite un selettore - la sintassi è abbastanza simile a jQuery.

  

Ciao mondo!

Erano qui.

In questo esempio HTML, daremo un'occhiata a come accedere alle informazioni nel secondo paragrafo, cambiarle e quindi produrre i risultati.

# crea e carica l'HTML include ('simple_html_dom.php'); $ html = new simple_html_dom (); $ HTML-> load ("

Ciao mondo!

Erano qui

"); # ottiene un elemento che rappresenta il secondo paragrafo $ element = $ html-> find (" p "); # modify it $ element [1] -> innertext. =" e siamo qui per restare. "; # emetterlo! echo $ html-> save ();

L'utilizzo del metodo find () restituisce sempre una raccolta (array) di tag a meno che non si specifichi che si desidera solo l'ennesimo child, come secondo parametro.

Righe 2-4: Carica l'HTML da una stringa, come spiegato in precedenza.

Linea 7: Questa riga trova tutto

tag nell'HTML e li restituisce come una matrice. Il primo paragrafo avrà un indice di 0 e i paragrafi successivi saranno indicizzati di conseguenza.

linea 10: Questo accede al secondo elemento nella nostra raccolta di paragrafi (indice 1) e aggiunge un'aggiunta al suo attributo innertext. Innertext rappresenta il contenuto tra i tag, mentre outertext rappresenta il contenuto incluso il tag. Potremmo sostituire completamente il tag usando il testo esterno.

Aggiungeremo un'altra riga e modificheremo la classe del nostro secondo tag di paragrafo.

$ element [1] -> class = "class_name"; echo $ html-> save ();

L'HTML risultante del comando di salvataggio sarebbe:

  

Ciao mondo!

Siamo qui e siamo qui per restare.

Altri selettori

Ecco alcuni altri esempi di selettori. Se hai usato jQuery, questi sembreranno molto familiari.

# ottiene la prima occorrenza di $ single = $ html-> find ('# foo', 0); # ottiene tutti gli elementi con $ collection = $ html-> find ('. foo'); # ottiene tutti i tag di ancoraggio in una pagina $ collection = $ html-> find ('a'); # ottiene tutti i tag di ancoraggio che si trovano all'interno dei tag H1 $ collection = $ html-> find ('h1 a'); # ottiene tutti i tag img con un titolo di 'himom' $ collection = $ html-> find ('img [title = himom]');

Il primo esempio non è del tutto intuitivo: tutte le query per le raccolte di ritorno predefinite, anche per una query ID, che dovrebbe restituire un solo risultato. Tuttavia, specificando il secondo parametro, stiamo dicendo "restituisci solo il primo elemento di questa collezione".

Ciò significa che $ single è un singolo elemento, piuttosto che un array di elementi con un elemento.

Il resto degli esempi è autoesplicativo.

Documentazione

La documentazione completa sulla libreria è disponibile nella pagina della documentazione del progetto.


Passaggio 3. Esempio di mondo reale

Per mettere in pratica questa libreria, scriveremo uno script veloce per analizzare i contenuti del sito Web Nettuts e produrre un elenco di articoli presenti nel sito per titolo e descrizione ... solo come esempio La raschiatura è un'area delicata del web e non dovrebbe essere eseguita senza permesso.

include ( 'simple_html_dom.php'); $ articles = array (); getArticles ( 'http://net.tutsplus.com/page/76/');

Iniziamo includendo la libreria e chiamando la funzione getArticles con la pagina in cui vorremmo iniziare l'analisi. In questo caso, stiamo iniziando verso la fine e siamo gentili con il server di Nettuts.

Stiamo anche dichiarando un array globale per semplificare la raccolta di tutte le informazioni dell'articolo in un unico punto. Prima di iniziare l'analisi, diamo un'occhiata a come viene descritto un riepilogo dell'articolo su Nettuts+.

Questo rappresenta un formato di post di base sul sito, inclusi i commenti al codice sorgente. Perché i commenti sono importanti? Contano come nodi per il parser.


Passaggio 4. Avvio della funzione di analisi

function getArticles ($ page) global $ articles; $ html = new simple_html_dom (); $ HTML-> LOAD_FILE ($ page); //… Di Più… 

Iniziamo in modo molto semplice rivendicando il nostro globale, creando un nuovo oggetto simple_html_dom, quindi caricando la pagina che vogliamo analizzare. Questa funzione chiamerà se stessa più tardi, quindi la stiamo configurando per accettare l'URL come parametro.


Passaggio 5. Trovare le informazioni che vogliamo

$ items = $ html-> find ('div [class = preview]'); foreach ($ articoli come $ post) # ricorda che i commenti contano come nodi $ articoli [] = array ($ post-> children (3) -> outertext, $ post-> children (6) -> first_child () -> outertext ); 

Questa è la funzione della funzione getArticles. Dare un'occhiata più da vicino per capire davvero cosa sta succedendo.

Linea 1: Crea una serie di elementi - div con la classe di anteprima. Ora abbiamo una collezione di articoli memorizzati in $ articoli.

Linea 5: $ post ora si riferisce a un singolo div dell'anteprima della classe. Se guardiamo l'HTML originale, possiamo vedere che il terzo figlio è l'H1 che contiene il titolo dell'articolo. Lo prendiamo e lo assegniamo a $ articles [indice] [0].

Ricordarsi di iniziare da 0 e contare i commenti quando si tenta di determinare l'indice corretto di un nodo figlio.

Linea 6: Il sesto figlio di $ post è

. Vogliamo il testo della descrizione dall'interno, quindi prendiamo il testo esterno del primo figlio - questo includerà il tag del paragrafo. Un singolo record in articoli ora assomiglia a questo:

$ articles [0] [0] = "My Article Name Here"; $ articles [0] [1] = "Questa è la mia descrizione dell'articolo"

Passaggio 6, impaginazione

La prima cosa che facciamo è determinare come trovare la nostra prossima pagina. Su Nettuts +, gli URL sono facili da capire, ma faremo finta che non lo siano, e ottenere il collegamento successivo tramite parsing.

Se guardiamo all'HTML, vediamo quanto segue:

"

Se c'è una pagina successiva (e non ci sarà sempre), troveremo un'ancora con la classe di 'nextpostslink'. Ora che le informazioni possono essere utilizzate.

if ($ next = $ html-> find ('a [class = nextpostslink]', 0)) $ URL = $ next-> href; $ HTML-> clear (); unset ($ html); getArticles ($ url); 

Sulla prima riga, vediamo se riusciamo a trovare un'ancora con la classe nextpostslink. Prendi nota speciale del secondo parametro per find (). Questo specifica che vogliamo solo il primo elemento (indice 0) della raccolta trovata restituita. $ next manterrà un solo elemento, piuttosto che un gruppo di elementi.

Successivamente, assegniamo il collegamento HREF alla variabile $ URL. Questo è importante perché stiamo per distruggere l'oggetto HTML. A causa di una perdita di memoria di riferimenti circolari php5, l'oggetto simple_html_dom corrente deve essere cancellato e rimosso prima che ne venga creato un altro. In caso contrario, potresti consumare tutta la memoria disponibile.

Infine, chiamiamo getArticles con l'URL della pagina successiva. Questa ricorsione termina quando non ci sono più pagine da analizzare.


Passaggio 7 Uscita dei risultati

Per prima cosa creeremo alcuni stili di base. Questo è completamente arbitrario: puoi rendere il tuo output come desideri.

#main margin: 80px auto; larghezza: 500px;  h1 font: grassetto 40px / 38px helvetica, verdana, sans-serif; margin: 0;  h1 a color: # 600; text-decoration: none;  p background: #ECECEC; font: 10px / 14px verdana, sans-serif; margine: 8px 0 15px; border: 1px #CCC solido; imbottitura: 15px;  .item padding: 10px; 

Ora inseriremo un po 'di PHP nella pagina per generare le informazioni memorizzate in precedenza.

"; echo $ item [0]; echo $ item [1]; echo"
";?>

Il risultato finale è una singola pagina HTML che elenca tutti gli articoli, a partire dalla pagina indicata dalla prima chiamata getArticles ().


Fase 8 Conclusione

Se stai analizzando una grande quantità di pagine (ad esempio, l'intero sito) potrebbe essere necessario più tempo del massimo tempo di esecuzione consentito dal tuo server. Ad esempio, eseguendo dal mio computer locale ci vuole circa un secondo per pagina (compreso il tempo di recupero).

Su un sito come Nettuts, con le attuali 78 pagine di esercitazioni, questa operazione durerebbe più di un minuto.

Questo tutorial dovrebbe iniziare con l'analisi HTML. Esistono altri metodi per lavorare con il DOM, incluso il PHP integrato in uno, che ti consente di lavorare con potenti selettori di xpath per trovare elementi. Per facilità d'uso e partenze veloci, trovo che questa libreria sia una delle migliori. Come nota conclusiva, ricorda sempre di ottenere il permesso prima di raschiare un sito; questo è importante. Grazie per aver letto!