Beim Web Scraping geht es ums automatische Extrahieren von Daten aus dem Internet. Z.B. möchte man die Aare-Temperatur herausfinden. Dazu gibt es z.B. die Webseite https://hydrodaten.admin.ch
Dort findet man in einer Tabelle die Wassertemperatur der letzten Messung. Allerdings ist der Wert in der Webseite – also in einem HTML-Dokument integriert. Möchte man mit dem Wert etwas berechnen, also z.B. ein Programm das einem bei einer Temperatur ab 18 Grad, sagt, man solle das Badezeugs einpacken, so geht das nicht. Für so ein Programm bräuchten wir nur den Wert als Zahl.
Hier kommen nun die Regulären Ausdrücke zum Einsatz: Man kann die Webseite mit einer Programmiersprache – z.B. Python anfordern – und dann im HTML-Code mit einem regulären Ausdruck die Stelle suchen, wo der Wert abgespeichert ist und diesen extrahieren.
Beispiel
Zuerst müssen wir uns den HTML-Code genau anschauen. Also öffnen wir die Webseite in einem Browser und wählen dort in den Entwicklungswerkzeugen den Eintrag Quelltext anzeigen (kann je nach Browser variieren). Oder wir machen einen Rechtsklick auf den Wert und wählen im Menu den Eintrag Element untersuchen.
Im Quelltext finden wir eine Tabelle wo der gesuchte Wert in der ersten Zeile an dritter Stelle steht:
<tr>
<td>
<div>Letzter Messwert</div>
<div class="opacity-75">11.09.2024 15:20</div>
</td>
<td>
<div>234</div>
<div class="opacity-75"></div>
</td>
<td>
<div>502.87</div>
<div class="opacity-75"></div>
</td>
<td>
<div>16.6</div>
<div class="opacity-75"></div>
</td>
</tr>
Wir können also nach <div>
suchen und alle Dezimalzahlen bis zum nächsten </div>
nehmen. Dann erhalten wir diese drei Werte, wobei der dritte der gesuchte ist.
Regexp
Der Reguläre Ausdruck könnte also wie folgt lauten:
<div>([\d|\.]*)</div>
Dabei wird das was wir extrahieren wollen in runden Klammern als Gruppe markiert: eine beliebig lange Folge von Ziffern \d
oder Punkten \.
.
Jetzt müssen wir einfach den dritten Eintrag wählen und wir haben unsere gesuchte Aare-Temperatur!
Code
Bis zu Zeile 7 wird die Webseite als String geladen.
Anschliessend muss nur noch der Reguläre Ausdruck angewandt werden und das 3. Element der Liste ausgewählt werden.
from urllib import request, parse
from re import findall
url = "https://www.hydrodaten.admin.ch/de/2135.html"
uf = request.urlopen(url)
html = str(uf.read())
print(html)
liste = findall("<div>([\d|\.]*)</div>", html)
print(liste[2])
Legal oder nicht
Wikipedia schreibt dazu:
Beim Scraping von Webseiten fremder Anbieter muss auf die Einhaltung der Urheberrechte geachtet werden, vor allem wenn die Inhalte über ein eigenes Angebot eingebunden werden. […] Einige Anbieter verbieten das automatische Auslesen von Daten auch explizit in den Nutzungsbedingungen.
Ein weiteres Problem stellt unter Umständen das Ausblenden von Informationen dar, etwa von Werbung oder rechtlich relevanten Informationen wie Disclaimer, Warnungen oder gar die automatische Bestätigung der AGB durch den [Web Scraper], ohne dass der Nutzer diese zu Gesicht bekommt.
Aufgaben
Aufgabe: Aare-Temperatur
Teste das obenstehende Beispiel aus. Erhältst du einen korrekten Wert?
Schaffst du es, neben dem Temperatur-Wert auch den Zeitpunkt der Messung zu extrahieren?
Aufgabe: Telefonsuche
Erstelle eine Telefonnummern-Suche für Python. Das Programm soll es ermöglichen mit Python bei tel.search.ch eine Suche zu tätigen und die Ergebnisse direkt in Python ausgeben.
mehr: Tipps «Aufgabe Telefonsuche»
- gehe auf https://tel.search.ch
- starte eine Suche die Ergebnisse liefert, z.B. «Optiker» in «Bern»
- schau dir die URL der Suchergebnis-Seite an
Schreibe ein Python-Skript
- das vom Benutzer die entsprechenden Eingaben verlangt
- diese zur URL zusammensetzt
- diese URL abruft
- und mit einem regulären Ausdruck die Ergebnisse extrahiert
Zusatzaufgabe
Kennst du eine Webseite die einen bestimmten Wert anzeigt. Versuche diesen mit Python zu extrahieren.
API
Viele Webseiten liefern solche Ergebnisse nicht mehr direkt im HTML-Code. So zeigt die Aare-Guru-Seite zwar die Temperatur an, wenn wir aber mit Python den Quelltext herunterladen, werden wir diese Messwerte nicht finden.
Wir sprechen von einer WebApp: Die HTML-Seite ist wie eine kleine Anwendung. Sobald der Browser sie lädt, wird die Anwendung im Browser ausgeführt. Jetzt werden die Messwerte von einer anderen URL geladen:
Ein Aufruf von dieser sogenannten API liefert ein JSON-Dokument. Hier sind die Daten strukturiert dargestellt:
{
"aare": 5.7,
"aare_prec": 5.69,
"text": "Iglu boue bringts meh",
"text_short": "Iglu boue",
"time": 1677585600,
"name": "B\u00e4rn",
"longname": "Bern, Sch\u00f6nau"
}
https://aareguru.existenz.ch/v2018/today?city=bern&app=my.app.ch&version=1.0.42
Die WebApp stellt jetzt diese Werte im Browser entsprechend dar und wir erhalten die Webseite mit den aktuellen Daten.