Open Source im professionellen Einsatz
Linux-Magazin 05/2006

Informationen aus Webseiten mit Tcl extrahieren

Angler-Paradies

Wer in seinen Programmen interessante Daten aus Webseiten weiterverarbeiten will, braucht einiges Geschick beim Herausfischen dieser Inhalte aus dem Sumpf von Formatierungsinfos, Abbildungen und interaktiven Abfragen. Tcl und eine Hand voll Module verhelfen ihm zu Angler-Ruhm und -Ehre.

999

Viele Daten-Fundgruben im Web oder im Intranet bereiten ihre Inhalte vor allem optisch auf - hübsche Seiten, die dem Auge des Betrachters schmeicheln. Für automatische Auswertungen braucht ein Programm die relevanten Informationen aber ohne Schnörkel und sauber in Häppchen zerlegt.

Idealerweise stellen Webserver dazu ihre Daten zusätzlich per SOAP bereit ([1], Simple Object Access Protocol). Wer diese glückliche Lage nicht vorfindet, schreibt kurzerhand eigene Tools, um die relevanten Daten aus der Seite zu extrahieren. Zwei Beispiele zeigen im Folgenden den kompletten Prozess vom Laden der Seite (was bei interaktiven Anwendungen schon eine Herausforderung ist) bis zum gezielten Aufspüren der gesuchten Daten (bei komplexen HTML-Layouts keine einfache Aufgabe).

Als Datenquelle für die Tcl-Skripte dienen die Pegelstände der Elbe bei Hamburg St. Pauli (Abbildung 1) sowie die Suchseite des Tclers Wiki (Abbildung 2).

Abbildung 1: Auf seiner Webseite veröffentlicht das BSH (Bundesamt für Seeschifffahrt und Hydrographie) unter anderem die Pegelstände der Messstation Hamburg St. Pauli. Ein Tcl-Skript extrahiert daraus die einzelnen Messwerte.

Abbildung 2: Auf der Eingangsseite des Tclers Wiki darf der Besucher nach beliebigen Stichworten suchen (rot umrahmt). Um diesen Ablauf nachzubilden, muss ein Skript die passende HTTP-Anfrage stellen.

Hergezaubert

Es gibt viele Möglichkeiten, Webseiten vom Server zu erhalten. Angefangen beim Abspeichern aus dem Browser über spezielle Programme wie Wget [2] bis zur direkten Kommunikation mit Tcl-Bordmitteln. Die Seite per Browser speichern ist sinnvoll, wenn der Anwender den Inhalt der Seite nur einmal benötigt. Erwartet die Webseite jedoch Parameter von dem Programm oder ändert sich der Inhalt häufig, dann ist das Abholen per Tcl bei weitem bequemer. Das klappt für einfache statische Seiten ebenso wie für dynamische Anfragen an einen Server, bei denen gewöhnlich der User ein Formular ausfüllt.

Auf seiner Webseite [3] stellt das Bundesamt für Seeschifffahrt und Hydrographie (BSH) die aktuellen Pegelstände der Elbe für die Station Hamburg St. Pauli bereit. Wie in Listing 1 zu sehen, ist das Laden einer Seite mit fester Adresse sehr einfach. Das Tcl-Skript verwendet dazu das »http«-Paket (Zeile 3), es gehört zum normalen Lieferumfang.

Der Befehl »http::geturl« lädt Dokumente von einem Webserver. Im einfachsten Fall genügt es, die URL anzugeben. Damit bei langsamen Netzverbindungen und überlasteten Servern das Programm nicht beliebig lange wartet, sorgt die »timeout«-Option (Zeile 10) dafür, dass der Befehl nach spätestens 10 Sekunden abbricht. Das Resultat ist in beiden Fällen ein Array mit den Server-Antworten. Es enthält neben dem Inhalt die Statusinformationen der Anfrage.

Listing 1: Pegelstände in
CSV wandeln

01 #!/usr/bin/tclsh
02 
03 package require http
04 package require dom
05 
06 ### Seite herunterladen
07 set url "http://www.bsh.de/aktdat/wvd/StPauli_pgl.htm"
08 
09 # Timeout in Millisekunden
10 set abfrageID [::http::geturl $url -timeout 10000]
11 
12 if [string match ok [http::status $abfrageID]] {
13     set inhalt [::http::data $abfrageID]
14     ::http::cleanup $abfrageID
15 } else {
16     puts stderr "Laden der Seite $url fehlgeschlagen"
17     puts stderr [http::status $abfrageID] [http::error $abfrageID]
18     ::http::cleanup $abfrageID
19     exit 1
20 }
21 
22 ### Messwerte auslesen
23 # Überflüssiges »</form>«-Element löschen
24 set zeilen [split $inhalt "n"]
25 set out [open pegel.html w]
26 foreach zeile $zeilen {
27     if [regexp {^</form>} $zeile] {
28         puts stderr "Lösche $zeile"
29     } else {
30         puts $out $zeile
31     }
32 }
33 
34 # Tidy aufrufen, um sauberes XML zu erhalten
35 if [catch {exec tidy -utf8 -i -o sauber.xml -asxhtml pegel.html} res] {
36     #puts $res
37 }
38 
39 # In DOM einlesen
40 set fd [open sauber.xml]
41 set inhalt [read $fd]
42 close $fd
43 set doc [dom::parse $inhalt]
44 
45 # Die Tabelle mit Pegelständen findet sich unter XPath:
46 # html/body/table/tr[5]/td/table/tr/td[2]/table/tr/td/table/tr[3]/td[2]/table[5]
47 
48 # Teil 1: html/body/table/tr[5]
49 set trs [dom::selectNode $doc //html/body/table/tr]
50 set tr  [lindex $trs 4]
51 # Teil 2: td/table/tr/td[2]
52 set tds [dom::selectNode $tr td/table/tr/td]
53 set td  [lindex $tds 1]
54 # Teil 3: table/tr/td/table/tr[3]
55 set trs [dom::selectNode $td table/tr/td/table/tr ]
56 set tr  [lindex $trs 2]
57 # Teil 3: td[2]
58 set tds [dom::selectNode $tr td]
59 set td  [lindex $tds 1]
60 # Teil 4: table[5]
61 set tables [dom::selectNode $td table]
62 set table  [lindex $tables 4]
63 
64 ### In CSV abspeichern
65 set fd [open pegelstand.csv w]
66 puts $fd "# Tag; Monat; Zeit; Pegelnull; Seekartennull"
67 foreach zeile [lrange [dom::selectNode $table tr] 2 end] {
68     foreach zelle [dom::node children $zeile] {
69         switch [dom::node cget $zelle -nodeName] {
70             th -
71             td {
72                 set text [string trim [dom::node stringValue $zelle]]
73                 puts -nonewline $fd  "$text;"
74             }
75             default {# andere Knoten ignorieren}
76         }
77     }
78     puts $fd ""
79 }
80 close $fd

Internetverbindungen arbeiten nicht immer zuverlässig, deshalb prüft in Zeile 12 der Aufruf »http::status« erst einmal den Zustand der Abfrage. Ist er okay, gibt »http::data« die vom Webserver gelieferten Daten aus. Das Programm speichert sie in der Variablen »inhalt« (Zeile 13). Im Fall eines Fehlers schreibt das Skript die Gründe für den Fehlschlag auf Stderr (falsche URL, Timeout und so weiter) und beendet sich. Nach dem Auswerten des Array löscht »http::cleanup« dessen Daten, um Speicher zu sparen. Insbesondere bei großen Dateien ist dieser Schritt ratsam.

Formularfrage

Statische Webseiten sind der einfachste Fall. Häufig präsentieren die Server ihre Informationen aber erst, nachdem der Besucher Daten in ein Formular eingetippt hat. Ein Beispiel hierfür ist das Tclers Wiki. Wie auf modernen Webseiten üblich enthält es eine Suchfunktion. Damit ein Tcl-Skript wie ein Webbrowser seine Anfrage an den Server stellen kann, muss der Programmierer die Zieladresse und die benötigten Parameter kennen. Am einfachsten erfährt er dies aus dem HTML-Code der Formularseite. Gerade bei Formularen verstecken sich die Parameter allerdings oft tief in der Formatierung.

Eingabefelder liegen bei HTML innerhalb eines »form«-Tag. Dies enthält die Definition von Eingabefeldern für Text (»input«-Tag), Comboboxen (»select«-Tag) oder Checkboxen (»input«-Tag vom Typ »radio«). Neben den Eingaben tragen manche Formulare zusätzliche Parameter, die der Benutzer nicht sieht (»input«-Tag, Typ »hidden«), der Browser aber unverändert an den Server übergibt. Eine gute Einführung in die genaue Definition von Formularen findet sich in der HTML-Bibel Selfhtml [4].

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Arbeitsmittel

    In der Tcllib sammeln Entwickler praktische Werkzeuge, die typische Programmieraufgaben lösen oder ganze Netzwerkprotokolle implementieren. Da sie sich auf eine reine Tcl-Erweiterung ohne kompilierten Code beschränkt, ist die Bibliothek sofort einsatzbereit. Dieser Streifzug stellt einige Teile vor.

  • Textarbeit

    Ob als Ascii-Editor oder für interaktive Anzeigen mit verschiedenen Schriften und Bildern - das Textwidget von Tk ist sehr flexibel einsetzbar. Diese Federlesen-Folge erklärt das Universalwidget anhand eines einfachen Editors und eines Readers für RSS-Dateien.

  • Der gute Ton

    Ob gesungen, geklimpert oder geblasen: Musikdateien gehören zum Inventar vieler Computer. Als Universalwerkzeug für Aufgaben rund um den guten Ton bewährt sich Tcl. Dank der Erweiterung Snack beherrscht es Sound in vielen Formaten, es spielt, bearbeitet und analysiert ihn.

  • Daten im Handgepäck

    Programme müssen ihre Daten nicht immer am SQL-Datenbankserver aufgeben: Für viele Aufgaben sind eingebettete Datenbanken die bessere Wahl. Jean-Claude Wippler hat mit Metakit eine DB-Engine entwickelt, die sehr sparsam mit den Ressourcen umgeht und dennoch einen großen Funktionsumfang bietet.

  • Taufrischer Federschmuck

    Tcl 8.5 steht kurz vor der Fertigstellung und bringt neben 50 Verbesserungen eine echte Überraschung mit: Die Basissprache erhält einen neuen Datentyp. Auch das eindrucksvolle Tile-Paket reift zusehends. Mit ihm nähert sich das Aussehen von Tk-GUIs dem anderer Widget-Bibliotheken.

comments powered by Disqus

Ausgabe 04/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.