Perl-Programmierung: LWP
Allgemeines zu LWP
BearbeitenLWP ist ein Perl-Modul, welches dem Programmierer hilft auf HTTP-Server, sprich auf World-Wide-Web-Seiten zuzugreifen. Das Modul gibt Perl eine ganze Bandbreite neuer Einsatzmöglichkeiten. Beispielsweise lassen sich damit Skripte schreiben, die Informationen aus mehreren Webseiten zusammentragen. Auch Webbots lassen sich damit realisieren. LWP arbeitet praktisch wie ein Browser, was es uns recht einfach macht, es zu benutzen, auch wenn die Arbeitsweise im Hintergrund recht komplex bleibt. Zusammen mit regulären Ausdrücken stellt LWP ein mächtiges Werkzeug dar.
Das UserAgent-Objekt und ein kleines Beispiel
BearbeitenDas UserAgent-Objekt ist Voraussetzung für jegliche Arbeit mit LWP. Es stellt wie oben genannt einen Browser dar und stellt sämtliche Methoden bereit, die wir für die Arbeit mit dem WWW in Perl brauchen. Die zwei am häufigsten benutzen Methoden sind wohl post und get. Wer sich bereits mit der Arbeitsweise von HTTP-Servern beschäftigt hat, dem werden die beiden Begriffe sicher keine Fremdworte sein. Also binden wir als allererstes sämtliche relevanten Module ein:
#!/usr/bin/perl
use strict;
use warnings;
use LWP 5.64;
Anschließend erzeugen wir ein UserAgent-Objekt:
my $browser = LWP::UserAgent->new();
Als ersten Test wenden wir die get-Methode auf de.wikibooks.org an:
my $seite = $browser->get('http://de.wikibooks.org');
Wir bekommen ein Objekt, das Seiteninhalt, MIME und andere Headerinfos von de.wikibooks.org speichert. Den eigentlichen Seiteninhalt erhalten wir mit der Methode decoded_content()
.
my $seite_code = $seite->decoded_content();
print $seite_code;
Wir erhalten nach dem Aufruf einer Webseite mit LWP reinen HTML-Code, den wir parsen und in jeder von uns gewünschten Form verarbeiten können.
Post-Zugriffe
BearbeitenMit Get-Zugriffen können wir jetzt Seiteninhalte abrufen. Das ist vielleicht praktisch, um sich beispielsweise Scripts zu schreiben, die von verschiedenen Websites Informationen zusammentragen und diese übersichtlich aufgelistet darstellen. Das wird mit der Zeit jedoch ein wenig witzlos. Manche LWP-Aufgaben verlangen von uns, der aufgerufenen Website Informationen mitzugeben. In HTML geschieht dies mithilfe von Forms. Das heißt, innerhalb des HTML-Dokuments befindet sich ein Codeblock, der in etwa so aussehen dürfte:
<form action = "http://www.server.net/verarbeiteanfrage.php">
<input type = "text" name = "text1">
<input type = "text" name = "text2">
</form>
Um mit LWP einer Form Daten mitzugeben, müssen wir den Aufbau dieser Form zuerst analysieren. Die LWP-Anfrage wird direkt an die in "action" eingetragene Adresse gestellt. D.h. die Daten sind in der Post-Anfrage bereits enthalten. Als nächstes müssen wir nachsehen, wie viele Input-Felder in der Form enthalten sind, da die Daten später in Form eines anonymen Hashs übergeben werden, welches die Feldnamen als Keys und die Inhalte als Values verwendet. Eine Post-Anfrage auf das oben dargestellte Beispielformular lautet folgendermaßen:
$seite = $browser->post('http://www.server.net/verarbeiteanfrage.php',[text1 => 'blabla',text2 => 'blablubb',]);
Starten wir also ein kleines Beispiel: Eine Suchanfrage nach einem Modul im CPAN
Bei der Analyse der Source von http://search.cpan.org stellen wir fest, dass die Anfrage an http://search.cpan.org/search gesandt wird. Das ist die aufzurufende URL. Des Weiteren hat die Form 2 Inputs: "query" und "mode". Der erste nimmt den Suchbegriff entgegen, der zweite grenzt den Suchbereich ein. Wir gehen also so vor, dass wir den User zuerst eine Suchanfrage eingeben lassen, anschließend die Anfrage machen und schlussendlich das Resultat der Anfrage ausgeben. Also ran an den Code.
#!/usr/bin/perl
use strict;
use warnings;
use LWP 5.64;
my $browser = LWP::UserAgent->new();
my $url = 'http://search.cpan.org/search';
print "Bitte geben sie den Suchbegriff ein:\n";
my $suchbegriff = <>;
chomp $suchbegriff;
# query = suchfeld,
# module = sucheingrenzung (geben wir einfach mal vor)
my $seite = $browser->post($url,[query => $suchbegriff, mode => 'module',]);
print $seite->decoded_content;
Wenn alles gut verlaufen ist, bekommen wir den HTML-Code der bearbeiteten Suchanfrage in den STDOUT geschrieben. Nächste Schritte in einer typischen LWP-Anwendung wären die Aufbereitung und grafische Ausgabe der Informationen.
Cookies
BearbeitenManchmal ist es nötig fuer LWP-Programme mit Cookies zu arbeiten. Um Cookies in LWP zu aktivieren, benötigen wir lediglich eine einfache Zeile Code:
$browser->cookie_jar({});
Hiernach kann der LWP::UserAgent Cookies von Browsern empfangen und speichern.
Sicher Programmieren
BearbeitenWer schon einmal ein Programm geschrieben hat, das im Netzwerk (auch dem Internet) arbeitet, der weiß sicherlich, wie schnell das eine oder andere Bit auf dem weg vom Sender zum Empfänger umkippen kann, wenn es schlecht läuft. Fehler im Netzwerk sind niemals auszuschließen und diese Fehler gilt es rechtzeitig zu erkennen und das Programm abzubrechen, bevor ein noch schwerwiegenderer Fehler entstehen kann. Dazu stellt uns das Rückgabe-Objekt zwei hilfreiche Attribute bereit. Das Attribut is_success (Boolescher Wert) gibt an, ob die Anfrage überhaupt geglückt ist. Das Attribut content_type (MIME-Typ) gibt an, welchen Typ von Daten der Server als Antwort auf die Anfrage zurückgeschickt hat. Angenommen, wir stellen eine Anfrage an einen Webserver und erwarten als Rückgabe text/html, so können wir die Korrektheit der Daten mit folgenden Zeilen überprüfen und das Skript gegebenenfalls abbrechen:
my $seite = $browser->get($url);
die "Die seite existiert nicht" unless $seite->is_success;
die "Der MIME-Typ der Rückgabe stimmt nicht, er sollte HTML sein, ist aber", $seite->content_type unless $seite->content_type eq 'text/html';
Wer einen Webspace besitzt, kann zu Testzwecken eine solche "Falschseite" aufsetzen und diese beiden Funktionen testen.