Scraping für alle

Eine der wichtigsten Fähigkeiten für Datenjournalisten*innen ist Scraping. Es ermöglicht uns, jegliche Daten herunterzuladen, die als Teil einer Webseite offen zugänglich sind, auch wenn sie nicht heruntergeladen werden sollen: seien es Informationen über die Abgeordneten des Bundestages oder - wie in unserem weihnachtlichen Beispiel - eine Liste der Weihnachtsmärkte in Deutschland.

2/7/2018

Es gibt einige Scraping Tools, die keine Programmierung benötigen und für viele Standard-Scraping-Aufgaben ausreichend sind. Programmierte Scraper können jedoch genau auf die jeweilige Aufgabe angepasst werden. Daher können einige kompliziertere Scraping-Aufgaben eine Programmierung erfordern.

Hier erklären wir drei Möglichkeiten des Scrapings: das Online-Tool import.io, für das keine Programmierung nötig ist, und das Schreiben eines Scrapers in R und Python – denn das sind die beiden häufigsten Programmiersprachen im Datenjournalismus. Wenn du dir aber die verschiedenen Tutorials durchliest, wirst du sehen, dass die Schritte zur Programmierung eines Scrapers gar nicht so unterschiedlich sind.

Scraping mit Import.io

Es benötigt zwei Schritte, um eine Website zu scrapen. Bei import.io musst du zunächst die für dich wichtigen Informationen auswählen. Dann extrahiert das Tool die Daten für dich, damit du sie herunterladen kannst.

Du beginnst, indem du import.io mitteilst, welche URL es sich ansehen soll, in diesem Fall die Adresse http://weihnachtsmarkt-deutschland.de. Wenn du einen neuen Extractor, wie import.io ihn nennt, startest, wirst du eine grafische Oberfläche sehen. Sie hat zwei Tabs: Bearbeiten zeigt die Website an. Import.io analysiert die Struktur der Website und versucht automatisch, strukturierte Informationen für die Extraktion zu finden und zu markieren. Wenn es nicht die richtigen Informationen ausgewählt hat, kannst du die Auswahl einfach ändern, indem du auf die Elemente der Website klickst, die dich interessieren.

Website mit der Liste der Weihnachtsmärkte

Im anderen Tab, Daten, zeigt das Tool die ausgewählten Daten als Tabellenkalkulation an, so wie die heruntergeladenen Daten aussehen werden. Wenn du zufrieden bist, klicke auf Daten von Website extrahieren.

Website geöffnet in import.io

Nun beginnt das eigentliche Scraping. Das kann ein paar Sekunden oder Minuten dauern, abhängig von der Datenmenge, die du dem Tool zum Scrapen gegeben hast. Und schon haben wir alle Weihnachtsmärkte in einem Dateityp deiner Wahl aufgelistet.

Scraping mit Python

Das Scraping einer Website besteht aus zwei Schritten. Zuerst lädst du den Inhalt aus dem Web herunter. Dann musst du die Informationen extrahieren, die für dich wichtig sind. Die gute Nachricht: Das Herunterladen einer Website ist kinderleicht. Die Hauptschwierigkeit beim Scraping ist der zweite Schritt, von der rohen HTML-Datei zu dem Inhalt zu kommen, den du wirklich willst. Aber keine Sorge, wir führen dich mit unserem Schritt-für-Schritt-Tutorial.

Lass uns zuerst zum einfachen Teil kommen: das Herunterladen der HTML-Seite aus dem Internet. In Python übernimmt die requests Bibliothek diese Aufgabe für dich. Installiere sie über pip und importiere sie in dein Programm. Um die Webseite herunterzuladen, musst du nur requests.get aufrufen und die Url übergeben, in diesem Fall die Adresse http://weihnachtsmarkt-deutschland.de. Get() wird ein Objekt zurückgeben und du kannst die heruntergeladene Webseite durch den Aufruf von response.text anzeigen lassen.

import requests

response = requests.get("http://weihnachtsmarkt-deutschland.de")
print(response.text)

Jetzt ist der gesamte Quelltext der Website mit allen Weihnachtsmärkten auf deinem Computer gespeichert. Du musst im Grunde nur die Datei säubern, alle HTML-Marker und den Text, der dich nicht interessiert, entfernen und die Weihnachtsmärkte finden. Informatiker*innen würden diesen Prozess Parsen der Datei nennen, also bist du dabei, einen Parser zu erstellen.

Bevor wir mit dem Parser beginnen, ist es hilfreich, die Website, die dich interessiert, zu inspizieren. Ein grundlegendes Verständnis von Frontend-Technologien ist sehr hilfreich, aber wir werden dich auch dann anleiten, wenn du noch nie eine HTML-Datei gesehen hast. Wenn du etwas Zeit hast, schau dir unser Tutorial zu HTML, CSS und Javascript an.

Jeder Browser hat die Möglichkeit, den Quellcode einer Website einzusehen. Je nach Browser musst du die Entwickler*innenoptionen aktivieren oder du kannst den Code direkt durch einen Rechtsklick auf die Webseite inspizieren. Unten siehst du einen Screenshot der Entwickler*innentools in Chrome. Auf der linken Seite findest du die Website – in diesem Beispiel die Weihnachtsmärkte. Auf der rechten Seite siehst du den HTML-Quellcode. Der beste Teil ist die Hervorhebung: Wenn du auf eine Zeile des Quellcodes klickst, wird die entsprechende Einheit der Website hervorgehoben. Klicke dich durch die Website, bis du das Codestück findest, das genau die Information kodiert, die du extrahieren willst: in diesem Fall die Liste der Weihnachtsmärkte.

Website-Struktur wie im Entwicklermodus gesehen

Alle Weihnachtsmärkte sind in einer Tabelle aufgelistet. In html beginnt eine Tabelle mit einem öffnenden <table> Tag, und sie endet mit dem schließenden </table>. Die Zeilen der Tabelle werden in html <tr> (Tabellenzeile) genannt. Für jeden Weihnachtsmarkt gibt es genau eine Zeile in der Tabelle.

Nun, da du dich mit der Struktur der Webseite vertraut gemacht hast und weißt, wonach du suchst, kannst du dich deinem Python-Skript zuwenden. Bs4 ist eine Python-Bibliothek, mit der man HTML-Dateien parsen und die HTML-Elemente daraus extrahieren kann. Wenn du sie noch nicht benutzt hast, installiere sie mit pip. Aus dem Paket importiere BeautifulSoup (weil der Name so lang ist, haben wir ihn im Import in bs umbenannt). Denke daran, dass der Code der Website in response.text steht. Lade ihn, indem du BeautifulSoup aufrufst. Da bs4 für verschiedene Dateitypen verwendet werden kann, musst du den Parser angeben. Für deine HTML-Bedürfnisse ist der ‘lxml’ Parser am besten geeignet.

from bs4 import BeautifulSoup as bs 
soup = bs(response.text,'lxml')

Nun wird die gesamte Website in BeautifulSoup geladen. Das Coole daran ist, dass BeautifulSoup das HTML-Format versteht. So kannst du ganz einfach nach allen möglichen HTML-Elementen im Code suchen. Die BeautifulSoup Methode ‘find_all()’ nimmt das HTML-Tag und gibt alle Instanzen zurück. Du kannst weiterhin die ID oder Klasse eines Elements angeben – aber das ist für die Weihnachtsmärkte nicht notwendig. Wie du schon gesehen hast, wird jeder Weihnachtsmarkt als eine Zeile in der Tabelle aufgelistet und mit einem <tr> Tag markiert. Du musst also nur alle Elemente mit dem </tr> Tag auf der Webseite finden.

rows = soup.find_all('tr') 
print(rows)

Und schon sind alle Weihnachtsmärkte in deiner Python-Ausgabe aufgelistet!

Allerdings sind die Daten noch recht unsauber. Wenn du einen zweiten Blick darauf wirfst, stellst du fest, dass jede Zeile aus zwei Datenzellen besteht, die mit <td> gekennzeichnet sind. Die erste ist der Name des Weihnachtsmarktes und verlinkt auf eine separate Webseite mit weiteren Informationen. Die zweite Datenzelle ist der Ort des Weihnachtsmarktes. Du kannst nun auswählen, an welchem Teil der Daten du interessiert bist. BeautifulSoup lässt dich den gesamten Text sofort extrahieren, indem du .text für das jeweilige Element aufrufst. Für jede Zeile erhältst du so den Namen des Weihnachtsmarktes.

for row in rows: 
     print(row.text)

Fertig! Jetzt hast du die Liste der Weihnachtsmärkte, mit der du arbeiten kannst.

Scraping mit R

Das Scraping einer Website besteht aus zwei Schritten. Zuerst lädst du den Inhalt aus dem Web herunter. Dann musst du die Informationen extrahieren, die für dich wichtig sind. Die gute Nachricht: Das Herunterladen einer Website ist kinderleicht. Die Hauptschwierigkeit beim Scraping ist der zweite Schritt, von der rohen HTML-Datei zu dem Inhalt zu kommen, den du wirklich willst. Aber keine Sorge, wir führen dich mit unserem Schritt-für-Schritt-Tutorial.

Lass uns zuerst zum einfachen Teil kommen: Das Herunterladen der HTML-Seite aus dem Internet. In R bringt das Paket rvest alle benötigten Funktionen mit. Install() und library() es (oder verwende needs()) und rufe read_html() auf, um das HTML von einer angegebenen URL zu lesen, in diesem Fall die Adresse http://weihnachtsmarkt-deutschland.de. Read_html() wird ein XML Dokument zurückgeben. Um die Struktur anzuzeigen, rufe html_structure() auf.

needs( 
     dplyr, 
     rvest ) 
doc <- read_html("http://weihnachtsmarkt-deutschland.de/") 
html_structure(doc)

Nun, da das XML-Dokument heruntergeladen ist, können wir die Knoten seiner Baumstruktur hinunterwandern, bis wir die Tabelle herausfinden können. Es ist hilfreich, die Website zu inspizieren, an der du interessiert bist. Ein grundlegendes Verständnis von Frontend-Technologien ist dabei sehr hilfreich, aber wir führen dich auch dann durch den Prozess, wenn du noch nie eine HTML-Datei gesehen hast. Wenn du etwas Zeit hast, schau dir unser Tutorial zu HTML, CSS und Javascript an.

Jeder Browser hat die Möglichkeit, den Quellcode einer Website einzusehen. Je nach Browser musst du die Entwickler*innenoptionen aktivieren oder du kannst den Code direkt durch einen Rechtsklick auf die Webseite inspizieren. Unten siehst du einen Screenshot der Entwickler*innentools in Chrome. Auf der linken Seite findest du die Website – in diesem Beispiel die Weihnachtsmärkte. Auf der rechten Seite siehst du den HTML-Quellcode. Der beste Teil ist die Hervorhebung: Wenn du auf eine Zeile des Quellcodes klickst, wird die entsprechende Einheit der Website hervorgehoben. Klicke dich durch die Website, bis du das Codestück findest, das genau die Information kodiert, die du extrahieren willst: in diesem Fall die Liste der Weihnachtsmärkte.

Website-Struktur wie im Entwicklermodus gesehen

Alle Weihnachtsmärkte sind in einer Tabelle aufgelistet. In html beginnt eine Tabelle mit einem öffnenden <table> Tag, und sie endet mit einem schließenden </table>. Die Zeilen der Tabelle werden in html <tr> (Tabellenzeile) genannt. Für jeden Weihnachtsmarkt gibt es genau eine Zeile in der Tabelle.

Nun, da du dich mit der Struktur der Website vertraut gemacht hast und weißt, wonach du suchst, kannst du dich wieder mit R beschäftigen.

Zunächst werden wir mit html_children() ein Nodeset aus dem Dokument doc erstellen. Diese findet alle Kinder des angegebenen Dokuments oder Knotens. In diesem Fall rufen wir es auf dem Haupt-XML-Dokument auf, also wird es die beiden Hauptkinder finden: <head> und <body>. Von der Inspektion des Quellcodes der Weihnachtsmarkt-Website wissen wir, dass <table> ein Kind von <body> ist. Wir können angeben, dass wir nur <body> und alle seine Kinder mit einem Index haben wollen.

doc %>% 
     html_children() -> nodes 
body <- nodes[2]

Nun müssen wir weiter eingrenzen, wir wollen wirklich nur die Tabelle und sonst nichts. Um das zu erreichen, können wir den entsprechenden <table> Tag mit html_node() ansteuern. Dies wird ein Nodeset mit einem Knoten, <table>, zurückgeben. Wenn wir nun die praktische html_table() Funktion verwenden – klingt, als wäre sie nur für uns gemacht worden! – können wir alle Informationen, die sich innerhalb dieser HTML-Tabelle befinden, direkt in einen Datenrahmen extrahieren.

body %>% 
     html_node("table") -> table_node 

table_node[[1]] %>% 
     html_table() -> df

Fertig! Jetzt hast du einen Datensatz, mit dem du arbeiten kannst.