HTML-Analyse und Screen Scraping mit der Simple HTML DOM Library

Wenn Sie HTML analysieren müssen, sind reguläre Ausdrücke nicht der richtige Weg. In diesem Lernprogramm erfahren Sie, wie Sie einen Open Source-Parser, einen leicht zu erlernenden Parser, verwenden, um HTML aus externen Quellen zu lesen, zu ändern und wieder auszuspucken. Am Beispiel von nettuts erfahren Sie, wie Sie eine Liste aller auf der Site veröffentlichten Artikel abrufen und anzeigen können.

Im Envato Market können Sie übrigens auch Parser finden, beispielsweise den HTML5-Parser.

HTML5-Parser auf dem Envato-Markt

Schritt 1. Vorbereitung

Als erstes müssen Sie eine Kopie der simpleHTMLdom-Bibliothek herunterladen, die bei sourceforge frei verfügbar ist.

Der Download enthält mehrere Dateien, aber die einzige, die Sie benötigen, ist die Datei simple_html_dom.php. Der Rest sind Beispiele und Dokumentation.


Schritt 2. Grundlagen der Analyse

Diese Bibliothek ist sehr einfach zu verwenden, es gibt jedoch einige Grundlagen, die Sie überprüfen sollten, bevor Sie sie in die Tat umsetzen.

HTML laden

$ html = new simple_html_dom (); // Laden aus einem String $ html-> load ('

Hallo Welt!

Waren hier

'); // Lade eine Datei $ html-> load_file ('http://net.tutsplus.com/');

Sie können Ihr Ausgangsobjekt erstellen, indem Sie entweder HTML aus einer Zeichenfolge oder aus einer Datei laden. Das Laden einer Datei kann entweder über eine URL oder über Ihr lokales Dateisystem erfolgen.

Ein Hinweis zur Vorsicht: Die load_file () -Methode delegiert ihren Job an file_get_contents von PHP. Wenn allow_url_fopen in Ihrer php.ini-Datei nicht auf true gesetzt ist, können Sie möglicherweise keine Remote-Datei auf diese Weise öffnen. Sie können in diesem Fall immer auf die CURL-Bibliothek zurückgreifen, um entfernte Seiten zu laden, und diese dann mit der load () -Methode einlesen.

Zugriff auf Informationen

Sobald Sie Ihr DOM-Objekt erworben haben, können Sie damit arbeiten, indem Sie find () verwenden und Sammlungen erstellen. Eine Sammlung ist eine Gruppe von Objekten, die über einen Selektor gefunden werden. Die Syntax ist jQuery sehr ähnlich.

  

Hallo Welt!

Waren hier.

In diesem Beispiel-HTML-Code wird beschrieben, wie Sie auf die Informationen im zweiten Absatz zugreifen, diese ändern und dann die Ergebnisse ausgeben.

# das HTML include erstellen und laden ('simple_html_dom.php'); $ html = new simple_html_dom (); $ html-> load ("

Hallo Welt!

Waren hier

"); # Holen Sie sich ein Element, das den zweiten Absatz darstellt. $ element = $ html-> find (" p "); # ändern Sie es $ element [1] -> innertext. =" und wir sind hier, um zu bleiben. "; # gib es aus! echo $ html-> save ();

Die find () -Methode gibt immer eine Auflistung (Array) von Tags zurück, es sei denn, Sie geben als zweiten Parameter an, dass Sie nur das n-te Kind möchten.

Zeilen 2-4: Laden Sie den HTML-Code wie zuvor beschrieben aus einem String.

Zeile 7: Diese Zeile findet alles

Tags im HTML-Code und gibt sie als Array zurück. Der erste Absatz hat einen Index von 0 und die folgenden Absätze werden entsprechend indiziert.

Zeile 10: Dadurch wird auf das zweite Element in unserer Sammlung von Absätzen (Index 1) zugegriffen und das Zusatztext-Attribut hinzugefügt. Innertext repräsentiert den Inhalt zwischen den Tags, während Outertext den Inhalt einschließlich des Tags darstellt. Wir könnten das Tag vollständig durch Outertext ersetzen.

Wir werden eine weitere Zeile hinzufügen und die Klasse unseres zweiten Absatz-Tags ändern.

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

Der resultierende HTML-Befehl für den Befehl save lautet:

  

Hallo Welt!

Wir sind hier und wir bleiben hier.

Andere Selektoren

Hier sind einige weitere Beispiele für Selektoren. Wenn Sie jQuery verwendet haben, werden diese sehr vertraut sein.

# Holen Sie sich das erste Vorkommen von $ single = $ html-> find ('# foo', 0); # hol alle Elemente mit $ collection = $ html-> find ('. foo'); # holt alle Ankertags auf einer Seite $ collection = $ html-> find ('a'); # holt alle Ankertags, die sich in H1-Tags befinden $ collection = $ html-> find ('h1 a'); # Holen Sie sich alle img-Tags mit dem Titel 'himom'. $ collection = $ html-> find ('img [title = himom]');

Das erste Beispiel ist nicht ganz intuitiv - alle Abfragen geben standardmäßig Sammlungen zurück, sogar eine ID-Abfrage, die nur ein einzelnes Ergebnis zurückgeben soll. Durch die Angabe des zweiten Parameters sagen wir jedoch "nur das erste Element dieser Sammlung zurückgeben"..

Das heißt, $ single ist ein einzelnes Element und nicht ein Array von Elementen mit einem Element.

Der Rest der Beispiele ist selbsterklärend.

Dokumentation

Die vollständige Dokumentation zur Bibliothek finden Sie auf der Seite Projektdokumentation.


Schritt 3. Beispiel aus der realen Welt

Um diese Bibliothek in die Tat umzusetzen, schreiben wir ein kurzes Skript, um den Inhalt der Nettuts-Website zu kratzen und eine Liste der auf der Website vorhandenen Artikel nach Titel und Beschreibung zu erstellen. nur als beispiel. Scraping ist ein schwieriger Bereich im Web und sollte nicht ohne Erlaubnis durchgeführt werden.

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

Wir beginnen damit, die Bibliothek einzuschließen und die Funktion getArticles mit der Seite aufzurufen, die wir analysieren möchten. In diesem Fall fangen wir am Ende an und sind freundlich zu Nettuts Server.

Wir deklarieren auch ein globales Array, um das Sammeln aller Artikelinformationen an einem Ort zu vereinfachen. Bevor wir mit dem Parsen beginnen, werfen wir einen Blick darauf, wie eine Artikelzusammenfassung auf Nettuts beschrieben wird+.

Dies stellt ein grundlegendes Post-Format auf der Site dar, einschließlich Quellcode-Kommentaren. Warum sind die Kommentare wichtig? Sie zählen als Knoten zum Parser.


Schritt 4. Starten der Analysefunktion

Funktion getArticles ($ page) globale $ articles; $ html = new simple_html_dom (); $ html-> load_file ($ page); //… Mehr… 

Wir beginnen ganz einfach, indem wir unser globales System beanspruchen, ein neues simple_html_dom-Objekt erstellen und dann die Seite laden, die wir analysieren möchten. Diese Funktion ruft sich später selbst auf, also richten wir sie so ein, dass die URL als Parameter akzeptiert wird.


Schritt 5. Die gewünschten Informationen finden

$ items = $ html-> find ('div [class = preview]'); foreach ($ items as $ post) # Die Kommentare zählen als Knoten. $ articles [] = array ($ post-> children (3) -> outertext, $ post-> children (6) -> first_child () -> outertext) ); 

Dies ist das Fleisch der getArticles-Funktion. Wir werden einen genaueren Blick darauf werfen, um wirklich zu verstehen, was passiert.

Linie 1: Erzeugt ein Array von Elementen - divs mit der Klasse der Vorschau. Wir haben jetzt eine Sammlung von Artikeln, die in $ items gespeichert sind.

Zeile 5$ post bezieht sich jetzt auf ein einzelnes Div der Klassenvorschau. Wenn wir uns den ursprünglichen HTML-Code anschauen, können wir sehen, dass das dritte Kind das H1 ist, das den Artikeltitel enthält. Wir nehmen das und ordnen es $ articles [index] [0] zu..

Denken Sie daran, bei 0 zu beginnen und Kommentare zu zählen, wenn Sie versuchen, den richtigen Index eines untergeordneten Knotens zu ermitteln.

Zeile 6: Das sechste Kind von $ post ist

. Wir möchten den Beschreibungstext von innen heraus, also greifen wir den Outertext des ersten Kindes auf - dies schließt das Absatz-Tag ein. Ein einzelner Datensatz in Artikeln sieht jetzt so aus:

$ articles [0] [0] = "Mein Artikelname hier"; $ articles [0] [1] = "Dies ist meine Artikelbeschreibung"

Schritt 6, Paginierung

Als erstes bestimmen wir, wie wir unsere nächste Seite finden. Bei Nettuts + sind die URLs leicht herauszufinden, aber wir tun so, als ob sie es nicht wären, und erhalten den nächsten Link per Parsing.

Wenn wir uns den HTML-Code anschauen, sehen wir Folgendes:

"

Wenn es eine nächste Seite gibt (und nicht immer), finden wir einen Anker mit der Klasse 'nextpostslink'. Nun können diese Informationen verwendet werden.

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

In der ersten Zeile sehen wir, ob wir mit der Klasse nextpostslink einen Anker finden können. Beachten Sie besonders den zweiten Parameter für find (). Dies gibt an, dass nur das erste Element (Index 0) der gefundenen Sammlung zurückgegeben werden soll. $ next enthält nur ein einzelnes Element und keine Gruppe von Elementen.

Als Nächstes weisen wir der Variablen $ URL den HREF des Links zu. Dies ist wichtig, da das HTML-Objekt gerade zerstört wird. Aufgrund eines php5-Zirkelreferenz-Speicherverlusts muss das aktuelle simple_html_dom-Objekt gelöscht und nicht gesetzt werden, bevor ein anderes erstellt wird. Andernfalls kann es sein, dass Sie Ihr gesamtes Gedächtnis aufbrauchen.

Zum Schluss rufen wir getArticles mit der URL der nächsten Seite auf. Diese Rekursion endet, wenn keine weiteren Seiten mehr analysiert werden müssen.


Schritt 7 Ausgabe der Ergebnisse

Zuerst werden wir ein paar grundlegende Stylings einrichten. Dies ist völlig willkürlich - Sie können Ihre Ausgabe nach Ihren Wünschen gestalten.

#main margin: 80px auto; Breite: 500px;  h1 font: fett 40px / 38px helvetica, verdana, serifenlos; Marge: 0;  h1 a color: # 600; Textdekoration: keine;  p background: #ECECEC; Schrift: 10px / 14px Verdana, serifenlos; Marge: 8px 0 15px; Grenze: 1px #CCC fest; Polsterung: 15px;  .item padding: 10px; 

Als Nächstes fügen wir ein kleines bisschen PHP in die Seite ein, um die zuvor gespeicherten Informationen auszugeben.

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

Das Endergebnis ist eine einzige HTML-Seite, in der alle Artikel aufgelistet sind, beginnend mit der Seite, die vom ersten getArticles () - Aufruf angegeben wurde.


Schritt 8 Schlussfolgerung

Wenn Sie viele Seiten analysieren (beispielsweise die gesamte Site), kann dies länger dauern als die maximale Ausführungszeit, die Ihr Server zulässt. Das Ausführen von meinem lokalen Computer dauert etwa eine Sekunde pro Seite (einschließlich Abrufzeit)..

Auf einer Website wie Nettuts mit aktuellen 78 Seiten mit Tutorials würde dies über eine Minute dauern.

Dieses Tutorial soll Ihnen den Einstieg in die HTML-Analyse erleichtern. Es gibt andere Methoden, um mit dem DOM zu arbeiten, einschließlich der eingebauten PHP-Methoden, mit denen Sie mit leistungsstarken Xpath-Selektoren nach Elementen suchen können. Für die einfache Verwendung und für einen schnellen Start finde ich, dass diese Bibliothek eine der besten ist. Denken Sie als Abschlussnotiz immer daran, die Erlaubnis einzuholen, bevor Sie eine Site abschaben. das ist wichtig. Danke fürs Lesen!