Webseiten mit PHP einlesen und analysieren
Content-Grabbing

DeveloperIT-ProjekteSoftware

PHP kann URLs auslesen und die so gewonnenen Daten mit Hilfe von String- oder Array-Funktionen sowie regulären Ausdrücken analysieren und verarbeiten.
Der folgende Workshop zeigt, welche Techniken und Methoden zur Verfügung stehen.

PHP in der Rolle des Browsers

Webseiten mit PHP einlesen und analysieren

Normalerweise läuft PHP als Teil eines Webservers und schickt Inhalte an die Browser der Anwender. Der typische Ablauf ist bekannt: Ein Client sendet via Browser eine Abfrage an den Server. Der erkennt zum Beispiel anhand der Endung, dass es sich um ein PHP-Skript handelt, und leitet es an den PHP-Interpreter weiter. Die von diesem erzeugten Ergebnisse schickt der Server dann an den Client.

Der Ablauf kann aber auch anders sein. Ein PHP-Skript kann auch einen entfernten URL quasi wie eine Datei behandeln, diesen öffnen, den Inhalt auslesen und nach Belieben manipulieren und Ergebnisse wahlweise an einen Client ausgeben, in einer Datei auf dem aufrufenden Server abspeichern oder in einer MySQL-Datenbank ablegen. Es gibt verschiedene Möglichkeiten, mit PHP einen entfernten URL zu lesen. Die Wahl der Mittel hängt davon ab, welche Anforderungen Sie bezüglich Einfachheit, Kontrollierbarkeit und Portabilität stellen.

Die Arbeit mit fopen() ist einfach und bequem, und sie folgt automatisch Umleitungen (Redirects). Wenn Sie also mit dieser Funktion das Verzeichnis http://www.example.com/people auslesen möchten und der Server Sie an http://www.example.com/people1 verweist, erhalten Sie den Inhalt der Index-Seite des Verzeichnisses, aber keine Nachricht darüber, dass der URL verlegt worden ist. Zu den Nachteilen von fopen() gehört, dass diese Funktion nur mit HTTP-GET-Anfragen umgehen kann (nicht mit HEAD oder POST) und Sie mit der Anfrage keine zusätzlichen Header oder Cookies versenden können. Außerdem können Sie mit ihr nur den Response-Body auslesen und keine Response-Header.


Fremde Seite auslesen

Webseiten mit PHP einlesen und analysieren

Ein Mini-Skript, das zum Beispiel der Startseite von Testticker.de (www.testticker.de) zu Leibe rückt, öffnet die durch den URL vorgegebene HTML-Datei und gibt die Datei zeilenweise ohne HTML-Tags wieder. Folgende Code-Zeilen sind dafür erforderlich:


$fd = fopen ("http://www.itespresso.de/", "r");
while (!feof($fd)) {
$buffer = fgetss($fd, 4096);
echo $buffer;
}
fclose ($fd);
?>

Mit zwei einfachen PHP-Befehlen lässt sich jegliches HTML-Markup entweder schon beim Einlesen oder später aus einer Variablen entfernen. Es handelt sich dabei um die Datei-Funktion fgetss() und die String-Funktion strip_tags.


Einlesen mit Markups

Webseiten mit PHP einlesen und analysieren


Seitenstruktur analysieren

Webseiten mit PHP einlesen und analysieren

Allerdings befriedigt das Ergebnis immer noch nicht ganz, insbesondere wenn es darum geht, einen bestimmten Ausschnitt aus der eingelesenen Seite zu extrahieren. Hier helfen nur weitere String-Funktionen von PHP und ein genauer Blick auf den Quellcode der Seite weiter.

Im folgenden Beispiel soll mit Hilfe einiger PHP-Funktionen die Link-Sammlung aus einem bestimmten Themengebiet aus der Anzeige des Open-Directory-Project Dmoz (www.dmoz.de) extrahiert werden.

Dazu zuerst ein Blick auf den Aufbau einer typischen Dmoz-Seite: Wenn Sie sich zum Beispiel über die Katalogstruktur zu den aktuellen Nachrichten in der Rubrik Medien vorarbeiten, können Sie aus dem Adressfeld des Browsers den URL für einen Direktaufruf der Seite ersehen. Er lautet: http://dmoz.org/World/Deutsch/ Medien/Aktuelle_Nachrichten/. Diese Seite muss das Skript also einlesen. Als Nächstes muss die Seite auf signifikante Strukturelemente untersucht werden, die dem Skript beim Extrahieren des gewünschten Absatzes helfen können. Sie sind unschwer und ohne einen Blick in der Quelltext der Seite zu erkennen: Die Link-Sammlung wird von zwei horizontalen Linien (


) eingerahmt und mit Hilfe von Listenelementen (
  • ) strukturiert.


    Dmoz-Seite einlesen

    Webseiten mit PHP einlesen und analysieren

    Damit lässt sich arbeiten: Es gilt also, die vierte horizontale Linie in dem eingelesenen String zu ermitteln, dann die fünfte und schließlich die dazwischen liegende Liste mit den gewünschten Informationen zu extrahieren. Das folgende Listing setzt diese Vorgaben um:


    // Einlesen der gesamten Seite in einen String
    $url = file_get_contents ("http://dmoz.org/World/Deutsch/ Medien/Aktuelle_Nachrichten/");

    //Ermitteln der Positionen der horizontalen Linien
    $erste_linie = strpos($url,"


    ");
    $zweite_linie = strpos($url,"

    ",$erste_linie+1);
    $dritte_linie = strpos($url,"

    ",$zweite_linie+1);
    $vierte_linie = strpos($url,"

    ",$dritte_linie+1);
    $fuenfte_linie = strpos($url,"

    ",$vierte_linie+1);

    //Extrahieren der Liste mit den Links
    $laenge = $fuenfte_linie - $vierte_linie;
    $linkliste = Substr($url, $vierte_linie + 4, $laenge - 4);

    //Ausgabe der Liste
    echo iconv("UTF-8", "ISO-8859-1", $linkliste);
    ?>

    Statt einer einfachen Ausgabe der extrahierten Daten kann natürlich auch eine weitere Bearbeitung erfolgen. Denkbar wäre zum Beispiel die Konstruktion einer eigenen Seite, in die das Extrakt eingebaut werden kann, oder einfach die Speicherung der Daten in einem File oder in einer Datenbank.


    Einbau in die eigene Seite

    Webseiten mit PHP einlesen und analysieren

    Um die Daten innerhalb einer eigene Seite nutzen zu können, ist es notwendig, den extrahierten Block weiter zu bearbeiten. Die vorhandenen Links sollen dabei Variablen zugeordnet werden, aus denen dann eine eigene, mit CSS formatierter Katalogseite produziert werden soll. Als grundlegendes Strukturelement wird dafür eine Tabelle verwendet. Zum Aufbau dieser Tabelle werden der eigentliche URL und der damit verbundene Text benötigt. Alle nötigen Daten befinden sich in der Variablen $linkliste. Diese wird wie folgt verarbeitet:


    //Links extrahieren
    $bereinigt = strip_tags ( $linkliste, "" );
    $links = explode (" foreach ($links as $value) {
    $link_ende = strpos($value,"
    ");
    $link = Substr($value, 0, $link_ende);
    echo "
    ";
    }
    ?>

    Der Rest ist dann HTML- und CSS-Feinarbeit. Am besten definiert man ein externes CSS-File, in dem zum Beispiel für die Links Hover-Effekte festgelegt werden. Außerdem muss man noch die statischen Elemente der Katalogseite festlegen. Der Aufbau der eigentlichen Tabelle erfolgt dann dynamisch an Hand des vorgestellten Skripts:

    echo "

    ";

    Ausweiten lässt sich das Prinzip natürlich auch. Statt einer Rubrik aus Dmoz extrahiert man gleich mehrere und baut die gewonnen Ergebnisse dann durch Zwischenüberschriften strukturiert nacheinander in die Tabelle ein.


    Seite nach Array

    Webseiten mit PHP einlesen und analysieren

    Es gibt noch weitere Varianten, Inhalte per PHP von fremden Seiten auszulesen und auf dem eigenen Server zu verarbeiten und zu nutzen. In bestimmten Fällen kann die Variante »Seite nach Array« Vorteile bieten. Vor allem dann, wenn es sich um eine statische Seite handelt, auf der sich die gesuchten Informationen in einem klar definierten und fixen Zeilenbereich befinden. Genutzt wird dafür die Dateifunktion file von PHP. Sie liest eine Datei (oder eben auch einen URL) zeilenweise in ein Array. Das bringt eine Menge Vorteile mit sich. Wenn Sie zum Beispiel wissen, dass die von Ihnen gewünschte Information auf den Zeilen 227 bis 327 der eingelesenen Webseite zu finden sind, kann das Grabbing mit ein paar Code-Zeilen nach folgendem Muster erfolgen:


    // Einlesen der gesamten Seite in ein Array
    $lines = file ("http://www.spiegel.de/schlagzeilen/");
    for ($i = 227; $i <= 327; $i++) {
    $bereinigt = strip_tags($lines[$i],"");
    echo $bereinigt."
    \n";
    }
    ?>


    RSS-Integration

    Webseiten mit PHP einlesen und analysieren

    Das Mini-Skript liest die aktuellsten Schlagzeilen von Spiegel Online aus.
    Das Verfahren eignet sich auch vorzüglich, um auf einen RSS-Feed zuzugreifen und diesen in eine eigene Seite zu integrieren. Im folgenden Beispiel wird dies demonstriert:


    // Einlesen des ZEIT-Newsfeeds in ein Array
    $lines = file ("http://newsfeed.zeit.de/politik/index");

    $item_1 = "".strip_tags($lines[9])."";
    $item_2 = "".strip_tags($lines[14])."";
    $item_3 = "".strip_tags($lines[19])."";
    $item_4 = "".strip_tags($lines[24])."";

    echo $item_1."
    ";
    echo $item_2."
    ";
    echo $item_3."
    ";
    echo $item_4."
    ";
    ?>

    Das Beispiel zeigt übrigens, dass die Funktion strip_tags auch bei reinem XML-Markup wirkt.


    Reguläre Ausdrücke

    Webseiten mit PHP einlesen und analysieren

    Wenn Sie die innerhalb eines HTML-Dokuments enthaltenen URLs herausziehen wollen, können Sie das auch mit Hilfe von regulären Ausdrücken (Regular Expressions) tun. Die folgende Funktion pc_link_extractor() kann dazu verwendet werden:


    function pc_link_extractor($s) {
    $a = array();
    if (preg_match_all('/]*)[\"\']?[^>]*>(.*?)<\/a>/i',$s,$matches,PREG_SET_ORDER)) {
    foreach($matches as $match) {
    array_push($a,array($match[1],$match[2]));
    }
    }
    return $a;
    }

    Und so können Sie diese Funktion in ein Skript einbinden

    $links = pc_link_extractor($page);

    Die Funktion pc_link_extractor() gibt ein Array zurück. Jedes Element dieses Arrays ist selbst wiederum ein Array, dessen erstes Element das Ziel des Links und dessen zweites Element den verlinkten Text enthält.

    Der reguläre Ausdruck in der Funktion erkennt nicht alle Links, zum Beispiel nicht solche, die mit Javascript oder mit hexadezimalen Escape-Sequenzen gebildet werden. Aber bei der Mehrzahl der einigermaßen wohlgeformten HTML-Seiten sollte es funktionieren.


    Arbeiten mit Snoopy

    Webseiten mit PHP einlesen und analysieren

    Im Web gibt es auch ein paar fertige Anwendungen, die beim Grabbing und bei der Verarbeitung fremder Web-Inhalte gute Dienste leisten können.

    Unter dem Namen Snoopy gibt es zum Beispiel eine PHP-Klasse, die einen Webbrowser simuliert, den man automatisch Webseiten laden und bearbeiten lassen kann. Snoopy liest auf Wunsch ganze Seiten und extrahiert den Text aus HTML-Dokumenten. Man kann mit dem Tool auch nur alle Links einer Seite sammeln. Zahlreiche weitere Funktionen wie das Setzen von User-Agents, Referrer und Cookies, die Erweiterung relativer Links zu absoluten und ein einfaches Übermitteln von Formulardaten stehen darüber hinaus zur Verfügung. Das Tool Snoopy benötigt eine PHP-Version mit Unterstützung für Perl-Compatible Regular Expressions. Die aktuelle Version kann man sich unter der Adresse snoopy.sourceforge.net aus dem Web laden.

    Die Fähigkeit von Snoopy, aus einer fremden Seite alle Links zu extrahieren, soll an folgendem Beispiel demonstriert werden.


    include "Snoopy.class.inc";
    $snoopy = new Snoopy;
    $snoopy->fetchlinks ("http://dmoz.org/World/Deutsch/Medien/ Journalismus/");
    $i=-1;
    while ($snoopy->results) {
    $i++;
    print "results[$i]."\">".$snoopy->results[$i]."
    ";
    }
    ?>

    Das kleine Skript holt sich alle Links von der angewählten Dmoz-Seite, wandelt die Ergebnisse in klickbare Hyperlinks um und gibt diese im Browser aus.

    Es zeigt sich, dass PHP eine ganze Menge Funktionen bereitstellt, mit denen sich HTML- oder XML-Seiten lesen und nach eigenen Wünschen bearbeiten lassen.