| Perl kann nicht nur auf das lokale Dateisystem zugreifen, sondern auch auf Live-Webseiten. | Hier wird gezeigt, wie man Daten von Webseiten liest und für den eigenen Bedarf weiter verwendet. |
Perl
|
Scripts für CGI und Systemverwaltung, Input / Output |
| Modul LWP | Browser-Objekt, HTTP-(GET)-Anforderung |
| Proxy | Zwischenstation auf dem Web zum Internet |
| HTTP-Request | Ausführen einer HTTP-(GET)-Anforderung |
| Header lesen | HTTP-Header lesen und analysieren |
| Inhalt lesen | HTML-Quelltext lesen, analysieren, anzeigen |
| Beispiel | Perl Demo-Programm zum Lesen von Live-Webseiten |
| Perl Module | Zusatz-Module zur Verarbeitung von Webseiten |
Perl-Modul LWP |
|
Modul LWPDas Lesen einer Webseite erfolgt mit einem Perl-Programm genauso wie mit einem Browser. Jeder einzelne Schritt wird im Perl-Programm 'nachgebaut'. Das Perl-Modul LWP enthält alle notwendigen Objekte und Methoden. Dieses Modul ist in allen gängigen Perl-Distributionen enthalten. |
use LWP; |
| Für die hier gezeigten Beispiele genügen die rechts gezeigten Teile des Moduls. |
use LWP::UserAgent;
use LWP::Simple; |
Browser-ObjektZuerst wird ein"Browser" (User Agent) definiert: Die Variable (hier $brs) enthält ein Browser-Objekt. |
$brs = LWP::UserAgent->new;
|
URLDie Adresse der gewünschten Webseite wird an eine Variable (hier $url ) zugewiesen. |
$url = 'http://www.perl.org';
|
Anforderung (Request)So wird ein HTTP → GET-Request formuliert. Damit werden nach → HTTP-Standard Daten von einem Webserver angefordert.Alternativ wird mit POST ein POST-Request formuliert oder mit HEAD lediglich der HTTP-Header (ohne den eigentlichen Inhalt) angefordert. |
$req = HTTP::Request->new(GET => $url);
|
Router (Proxy-Server) |
|
|
In einem lokalen Netzwerk (LAN) hat nur 1 Computer direkten Zugang zum Internet.
Dieser PC dient als Router: Der Internet-Verkehr aller anderen PC wird über den
Router geleitet. ♦ Details zu IP-Adresse, Port, Router |
Auf jedem einzelnen Browser auf jedem PC des Netzwerks muss (IP)-Adresse und Port des
Routers (Proxy-Servers) eingestellt werden. Das kann manuell oder automatisch erfolgen. Die gleiche Aufgabe muss auch in einem Perl-Programm ausgeführt werden. |
Proxy automatisch konfigurierenAuf Linux Systemen gibt es normalerweise eine Umgebungs-Variable HTTP_PROXY, welche Adresse und Port des Proxy-Servers angibt.Die Methode hat den Vorteil automatischer Anpassung: Das Perl-Script verwendet auf jedem PC den jeweiligen Internet-Zugang. Nachteil: Die Methode versagt, wenn die Umgebungs-Variable nicht existiert - Das trifft z.B. auf alle Windows-Systeme zu. |
$brs = LWP::UserAgent->new; $brs->env_proxy; Am eigenen Server oder PC kann man die Umgebungs-Variable HTTP_PROXY auf auf Windows manuell anlegen oder vom Webserver für CGI-Hilfsprogramme anlegen lassen (Apache Konfigurations-Anweisung SetEnv) |
Proxy explizit angebenDiese Methode ist weniger flexibel als die automatische Konfiguration, funktioniert dafür in jedem Fall und auf jedem Betriebssystem.Wichtig: Die Proxy-URL muss das Protokoll (http://) und den Port (hier 2345, zu ersetzen durch den Port ihres Routers ) enthalten. |
$brs = LWP::UserAgent->new;
$proxy_url = 'http://192.168.0.1:2345';
$brs->proxy(http => $proxy_url);
|
HTTP-Request ausführen |
|
|
Wenn der HTTP-Request (mit oder ohne
↑ Proxy) formuliert wurde, kann er ausgeführt werden. Der gleiche Vorgang wird von einem Browser ausgeführt, wenn man in der Adressezeile die Eingabe-Taste (enter, return) drückt. Die Methode is_success() gibt Auskunft, ob vom adressierten Webserver eine Antwort erhalten wurde. Die maximale Wartezeit (timeout, normalerweise 180 sec) ist einstellbar. |
$resp = $brs->request($req);
if($resp->is_success()) { print "Erfolg !";
}else { print "Keine Antwort !";
}
|
HTTP-Header |
|
|
Wenn der HTTP-Request erfolgreich war, dann sendet jeder Webserver
vor dem eigentlichen Inhalt einen HTTP Header. Das ist ein kurzer Text-Block mit einigen Angaben zur Ankündigung des nachfolgenden Inhalts. Ein HTTP-Header wird vor allen Daten gesendet, auch vor Bildern, Sounds, einfachen Texten usw. |
Der HTTP-Header wird normalerweise vom Browser nicht angezeigt. ♣ Tipp: Einige Firefox-Plugins (Header Spy, Live HTTP Headers) erlauben die Anzeige des HTTP-Headers. Live HTTP Headers zeigt sowohl den GET-Request des Browsers als auch den HTTP-Header des Servers an. |
HTTP Status CodeDer wichtigste Teil des HTTP-Headers ist die erste Header-Zeile. Sie enthält den Status Code (♦ Details). Bekannte Status Codes sind z.B. 200 OK oder 404 Not Found. (Dokument nicht gefunden). |
Ausgabe des HTTP Status-Code: print $resp->status_line;
|
HTTP Header AusgabeDas Beispiel zeigt die einfache Ausgabe des gesamten HTTP-Headers, z.B. für Debug-Zwecke. |
Ausgabe des gesamten Headers:
print $resp->headers_as_string();
|
Analyse des HTTP HeadersJeder Browser analysiert den erhaltenen HTTP Header. Die Header-Daten dienen zur näheren Beschreibung der nachfolgenden 'eigentlichen' Daten. Zur Analyse wird der Text in Zeilen aufgespalten. Jede Zeile enthält genau eine Header-Variable in der FormName: Wert
Die Auswertung der Variablen erfolgt am besten mit Hilfe von Regulären Ausdrücken
(→ RegExp).
|
Aufspaltung in Zeilen (zur Analyse des Inhalts):
$hs = $resp->headers_as_string();
@ahs = split(/\n/,$hs); $hlen = @ahs; print "$hlen Zeilen:\n"; foreach $line(@ahs) { print $line;
}
|
Inhalt von Webseiten lesen |
|
Inhalt (content)► Wenn der ausgeführte Auftrag (Request) erfolgreich war (HTTP → Status-Code 200 OK), dann wird der Inhalt an eine Variable zugewiesen. Die Variable (hier $content) enthält dann die angeforderten Daten, das ist z.B. bei einer Webseite deren gesamter HTML-Quelltext.► Tipp: Prüfen sie zuerst, ob überhaupt ein Inhalt gefunden wurde (Beispiel rechts). |
$content = $resp->content;
if(defined $content) { print "Webseite $url gelesen\n";}
}else { print "Fehler beim Lesen von $url\n";}
}
|
Text-ZeilenEin Text wird am am besten in handliche Teile zerlegt, z.B. in ein → Array von Zeilen.Bei Zerlegung mit Funktion split wird das zur Spaltung verwendete Zeichen (hier \n = newline) jeweils entfernt. Im Beispiel wird zusätzlich die Anzahl der erhaltenen Zeilen ausgegeben. |
@zeilen = split(/\n/,$content);
$anz = @zeilen; print "Anzahl Zeilen = &anz\n"; |
Ausgabe an der KonsoleIn jedem Durchlauf der Schleife wird aus dem Array @zeilen eine Zeile $line verarbeitet. Im Beispiel wird als Verarbeitung lediglich der Text ausgegeben. In der Praxis sucht man meist nach einem bestimmten Inhalt, der analysiert und weiter verarbeitet wird. Dazu werden Reguläre Ausdrücke (→ RegExp) verwendet. |
foreach $line(@zeilen) {
print "$line\n";
}
# Hier verarbeiten
|
Ausgabe auf einer Webseite► Wenn man HTML-Quelltext auf einer → Webseite ausgibt, dann muss der Text HTML-codiert werden. Dabei werden alle HTML-Anweisungen 'maskiert', damit sie nicht ausgeführt sondern als Text angezeigt werden.♦ Details zur Makierung von HTML-Zeichen Zur HTML-Maskierung wird die Funktion encode_entities aus dem Perl-Modul HTML verwendet. Beispiel: Der HTML Quelltext <body> wird in den Text <body> umgewandelt. Dieser Text wird auf einer Webseite korrekt angezeigt. |
use HTML::Entities;
foreach $line(@zeilen) {
$hline = encode_entities($line);
}
print "$hline\n"; |
Beispiel |
|
|
Die erforderlichen Methoden sind derzeit auf dem Webserver von PS-Trainer nicht zugelassen. Beispiel: Anzeige des → HTTP-Headers von Webseiten → LWP-Test, → header-test |
Alternativ können sie das hier gezeigte
Demo-Script kopieren und selbst
ausprobieren, wenn sie Perl installiert haben. In allen üblichen → Linux-Distributionen ist Perl selbstverständlich enthalten. ♦ Details zur Installation von Perl auf Windows |