Perl-Skript holt dynamisch generierte Werte aus Webseiten
Abgesaugt
Gibt es kein API für das Einsammeln von Webinformationen, hilft oft Perl mit der Brechstange des Screenscraping. Seit Neuestem überwindet es dabei sogar die Hürde Javascript.
© Gunnar Pippel, 123RF
Gibt es kein API für das Einsammeln von Webinformationen, hilft oft Perl mit der Brechstange des Screenscraping. Seit Neuestem überwindet es dabei sogar die Hürde Javascript.
Nicht weniger als drei ehrwürdige Linksys-Router schaufeln die Ethernet-Pakete im Wohnbereich der Perlmeister-Labs umher. Auf allen dreien tut die Tomato-Firmware [2] seit Jahren ohne jeglichen Störfall ihren Dienst. Da Tomatos Admin-Webseite nicht nur allerlei nützliche Einstellungen erlaubt (Abbildung 1), sondern darüber hinaus noch informative Statusdaten anzeigt, lag es nahe, einen Screenscraper zu schreiben, um die Daten in regelmäßigen Abständen auf den PC zu holen, in einer Datenbank zu speichern und bei auffälligen Ausreißern Alarm auszulösen.
Der erste Versuch allerdings ging daneben: Beim Einholen der mit Basic Auth gesicherten Seite via »wget http://root:Passwort@192.162.0.1«
zeigte sich, dass Tomato die Felder der Anzeige mittels Javascript auffrischt und einfache Webscraper wie das Perl-Modul WWW::Mechanize statt der begehrten Uptime-Zeit lediglich Javascript-Code runterladen (Abbildung 2).
Damit die Seite die Daten richtig anzeigt, muss auf Client-Seite eine Javascript-Engine anlaufen, die den Code interpretiert und gemäß den darin enthaltenen Anweisungen das DOM (Document Object Model) der im Browser dargestellten Seite auffrischt. Einfache Screenscraper tun das nicht, sondern verhalten sich wie Browser mit abgeschaltetem Javascript und erhalten daher nicht das eigentlich gewünschte Ergebnis.
Die herkulische Aufgabe, diese Browseraktionen in Perl zu implementieren, hat das CPAN-Modul WWW::Scripter erledigt. Zusammen mit dem Plugin WWW::Scripter::Plugin::Ajax für Serverrückrufe, der DOM-Schnittstelle HTML::DOM und der Pure-Perl-ECMA-Skript-(Javascript)-Engine JE stellt es alle notwendigen Funktionen bereit.
Wenn man darüber nachdenkt, wie viele DOM-spezifische Unterschiede bei Browsern es allein zwischen dem Internet Explorer und Firefox gibt, dann lässt sich erahnen, wie viel Arbeit in den Modulen steckt. Außerdem verhält sich das Modul wie ein weiterer Browser, Unterschiede zwischen seiner Implementierung und dem sonst verwendeten Desktopbrowser sind unvermeidlich. Eine weitere Möglichkeit, einen Javascript-gesteuerten Skriptclient zu implementieren, wäre der Einsatz einer Browser-Fernsteuerung wie Selenium [3].
Listing 1 zieht zunächst WWW::Scripter herein und lädt das separat erhältliche Ajax-Plugin mit der Methode »use_plugin()«
. Die Klasse ist von WWW::Mechanize und damit auch von LWP::UserAgent abgeleitet und unterstützt demnach die Methode »get()«
zum Einholen von Webseiten. Da der Router beim HTTP-Zugang nach einem Passwort für den Rootaccount fragt, stellt das Skript dieses mittels der ebenfalls ererbten Methode »credentials()«
zur Verfügung.
Listing 1
tomato-overview
01 #!/usr/local/bin/perl -w
02 use strict;
03 use WWW::Scripter;
04 use Sysadm::Install qw(:all);
05 use HTML::TreeBuilder::XPath;
06
07 my $w = WWW::Scripter->new();
08 $w->use_plugin('Ajax');
09
10 my $pw = slurp "pw.txt";
11 chomp $pw;
12 $w->credentials( "root", $pw );
13 $w->get('http://192.168.0.1');
14
15 $w->wait_for_timers( max_wait => 1 );
16
17 my $tree= HTML::TreeBuilder::XPath->new();
18 $tree->parse( $w->content() );
19 my $uptime =
20 $tree->findvalue(
21 '/html/body//tr[@id="uptime"]/' .
22 'td[@class="content"]');
23
24 print "uptime: $uptime\n";
Damit das Passwort nicht hart im Skript kodiert ist, liest es die Funktion »slurp()«
aus der Datei »pw.txt«
im aktuellen Verzeichnis ein. Die Datei enthält nur eine Zeile mit dem Passwort und sollte gegen unberechtigte Lese- oder gar Schreibzugriffe geschützt sein. Ganz astrein ist diese Lösung freilich nicht, doch irgendwie muss ich den Schlüssel unter der Fußmatte verstecken, wenn das Skript automatisch laufen soll und der User nicht jedes Mal das Passwort tippen kann.
Umfang: 3 Heftseiten
Preis € 0,99
(inkl. 19% MwSt.)
Alle Rezensionen aus dem Linux-Magazin
Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...