Automatisiertes Web Scraping

Heute zeige ich euch, wie man repetitive Internet-Recherchen automatisieren kann. Wir basteln uns zunächst unseren eigenen Web Scraper, der für uns die gewünschten Informationen aus dem Netz zieht. Im Anschluss erstellen wir einen Cronjob, der unser Programm zu gewünschten Zeitpunkten automatisch für uns ausführt.

Unser aller Zeit ist kostbar und die meisten von uns versuchen die 24 Stunden, die uns pro Tag zur Verfügung stehen, so effizient wie möglich zu nutzen, damit wir neben der Erfüllung all unserer Aufgaben auch noch ein bisschen Zeit für die schönen Dinge des (Arbeits-)Lebens haben.

Wie nervig sind da bitte repetitive Aufgaben? Diese kosten uns nicht nur viel Zeit, meist sind sie auch noch recht anspruchslos… Nein, ich spreche nicht vom täglichen Gang zur Mülltonne 😉 Dafür habe ich leider noch keine digitale Lösung in petto. Aber achtet mal darauf, wie viele Tätigkeiten ihr an eurem Computer immer wieder auf die exakt gleiche Weise durchführt. Ich wette, da fällt allen auf Anhieb etwas ein.

OK, aber was können wir dagegen tun, unsere wertvolle Zeit mit diesen Aufgaben zu verplempern?

Das Lösungswort lautet „Automatisierung“.

Automatisierung ist nicht nur ein Kampfbegriff aus der Hightech-Branche, sondern eine Möglichkeit für uns alle, unliebsame, repetitive Aufgaben von unseren Computern erledigen zu lassen.

Ich will euch heute an einem Beispiel aus meinem Arbeitsleben zeigen, wie so etwas funktionieren kann. Als Freiberufler halte ich immer die Augen nach neuen Projekten offen, in die ich meine Expertise einbringen kann (= Euphemismus für „auch ich muss schauen, dass ich Geld verdiene“ 😉 ). Das mache ich z.B. bei Webportalen, in die ich bestimmte Schlagworte eingebe, durch die Ergebnis-Seiten klicke und beim Durchstöbern die einzelnen Einträge/Ausschreibungen/Angebote mit meinen Expertisen matche.

Laaaaangweilig und repetitiv!!! Wir schreiben uns also heute ein Programm, das diese Aufgabe für ein solches Programm löst und bedienen uns dafür des sogenannten Web Scrapings, laden uns also mit diesem Programm Daten aus dem Web herunter.

Als Beispiel habe ich dafür mal die Ausschreibungssuche der e-Vergabe-Plattform des Bundes herausgesucht, da diese einige Schwierigkeiten mit sich bringt, die wir in diesem Tutorial lösen werden, um euch so hoffentlich bei ähnlichen Projekten das Leben leichter zu machen.

Schritt 1: Seite inspizieren

Als allererstes schauen wir uns die robots.txt-Datei der Seite an. Dazu muss man lediglich ‚robots.txt‘ an die Basis-URL der Seite anhängen (sprich https://www.evergabe-online.de/robots.txt). Diese Seite enthält Hinweise darauf, welche URLs von Web-Crawlern nicht abgerufen werden SOLLEN (mehr Infos zum Robots Exclusion Standard findet ihr hier). In unserem Beispiel ist die ’search‘-URL nicht betroffen und wir können ohne schlechtes Gewissen fortfahren.

Nun schauen wir uns die einzelnen Elemente der Seite an. Zum Beispiel gibt es auf der Seite einen User-Input „Suchbegriff“, ein Dropdown-Menü für den Zeitpunkt der Veröffentlichung und einen „Suchen“-Button. Um die html-Informationen zu diesen Elementen zu erlangen, die wir im Anschluss für unser Programm brauchen, reicht ein Rechtsklick auf das Element und ein Klick auf „Inspect Element“ (Safari) oder „Inspect“ (Chrome).

Wenn wir einen Suchbegriff (unser Programm soll nach den Begriffen „Umwelt“ und „Natur“ suchen) auf der Seite eingeben, erhalten wir eine Ergebnistabelle. Auch diese müssen wir inspizieren. Sie hat mehrere Spalten und Zeilen und vor allem hat sie mehrere Seiten, die wir irgendwie ansteuern müssen. Wenn wir uns die hinterlegten html-Links anschauen, sehen wir, dass die IDs der durchnummerierten Seiten leider keiner mir nachvollziehbaren Logik folgen. ABER es gibt einen ’next‘-Button (das „>“-Symbol) mit dem wir dieses Problem umgehen können, indem wir unser Programm einfach wiederholt diesen Button drücken lassen, bis wir auf der letzten Seite angekommen sind.

Schritt 2: Den Web Scaper schreiben

Bevor wir mit dem Programmieren loslegen, erstellen wir uns noch schnell ein „virtual environment“ und installieren in dieses alle Bibliotheken, die wir später benötigen (d.h. BeautifulSoup, Pandas, Selenium, Math, Time, Re, Datetime). Ich mache das für all meine Projekte, damit ich sicherstellen kann, dass meine Projekte auch noch in Jahren genau so funktionieren, wie ich sie einst konzipiert hatte und nicht durch Updates von Python oder Bibliotheken zerschossen werden. Ich nutze dazu den Manager Conda (Anleitung zu Installation und Bedienung hier).

Nun aber wirklich ans Eingemachte. Zunächst erstellen wir ein neues Skript in Python mit dem Namen „webscraper.py“ und importieren alles nötige.

Im Anschluss schreiben wir die erste von zwei Funktionen. Diese habe ich mit Bedacht sehr generell gehalten (die Parameter „Stichwort“ und „Zeitraum“ sind einstellbar), um die Wiederverwendung dieser Funktion in anderen Programmen zu ermöglichen.

Wie ihr seht ist die Funktion relativ mächtig, daher können wir an dieser Stelle nicht auf jedes Detail eingehen. Ich versuche dennoch euch einen Überblick über die Funktionalität zu geben:

Zunächst definieren wir, mit welchem Treiber/Browser wir arbeiten, ziehen uns die gewünschte URL heran und geben in der Suchmaske die gewünschten Parameter ein. Dann drücken wir den „Suchen“-Button (Zeile 1 bis 13). Ihr wundert euch vielleicht über die Wartezeiten, die ich eingebaut habe. Unser Programm würde normalerweise einfach jeden programmierten Schritt abarbeiten und könnte in wenigen Augenblicken fertig sein. Aber die Seite mit der wir arbeiten muss ja ausreichend Zeit zum Laden haben. Dafür sind die Wartezeiten gedacht.

Dann ziehen wir uns die Gesamtzahl der Ergebnisse der Seite heran und berechnen damit, wie viele Seiten die Ergebnistabelle hat (Zeile 16 bis 19). Das ist später wichtig, da wir dem Programm ja irgendwie sagen müssen, wie oft der „Next“-Button zu drücken ist.

Nun schreiben wir uns leere Listen für alle Elemente der Ergebnistabelle, die wir einfangen wollen (Zeile 20 bis 26).

Und nun geht’s ans Eingemachte: Wir schreiben uns eine for-Schleife, die in eine while-Schleife eingebettet ist (Zeile 28 bis 52). Die while-Schleife durchläuft alle Seiten der Tabelle, greift dabei deren Inhalt ab und zerpflückt ihn in die einzelnen Zeilen der Tabelle. Dann wird in der for-Schleife jede Zeile der Teil-Tabelle durchlaufen. Dabei wird der Text-Inhalt der einzelnen Zellen extrahiert und der entsprechenden Liste angehängt.

Im Anschluss wird über eine if-Abfrage geklärt, ob es noch eine weitere Ergebnisseite gibt und, falls ja, der „Next“-Button geklickt. In diesem Falle durchläuft die while-Schleife eine weitere Runde.

Sind alle Ergebnisseiten abgegriffen, erstellen wir aus den gefüllten Listen einen Dataframe (ein Datensatz mit Tabellenstruktur; Zeile 58 bis 61), schließen den Driver/Browser (Zeile 62) und geben den Dataframe zurück (Zeile 63).

Puh, das schwerste haben wir hinter uns 🙂

Nun schreiben wir uns noch eine zweite, deutlich weniger komplexe Funktion:

In dieser lassen wir nun unsere erste Funktion zweimal durchlaufen, einmal mit dem Suchbegriff „Umwelt“ und einmal mit „Natur“ (Zeile 2 bis 3).

Dann verschmelzen wir die erhaltenen Dataframes und löschen eventuell vorhandene Duplikate (Zeile 5 bis 6).

Den kombinierten Datensatz filtern wir nun nach weiteren Schlagworten, indem wir die Beschreibung der Projekte in einen String konvertieren und darauf prüfen, ob bestimmte Substrings enthalten sind (bei mir haben diese natürlich alle etwas mit Datenanalyse zu tun; Zeile 8 bis 12).

Nun brauchen wir nur noch das heutige Datum und können, falls der Datensatz nicht leer ist (= keine Treffer), diesen als csv-Datei mit dem Datum des heutigen Tages im Dateinamen abspeichern (Zeile 14 bis 18).

Jetzt nur noch ein winziger Code-Schnipsel und wir haben es geschafft. Dieser macht das Programm multifunktional: wir können das Programm als Modul importieren und beispielsweise nur die erste Funktion in anderen Programmen nutzen. Wir können durch diesen Zusatz das Programm aber auch eigenständig laufen lassen; dann wird die zweite Zeile dieses Snippets ausgeführt, das Programm läuft komplett durch und speichert uns die Projekte, die mit unseren Suchbegriffen in den letzten sieben Tagen auf der Plattform hinzugekommen sind.

Schritt 4: Automatisierung

Fertig!!! 🙂

Oder? Nicht ganz. Nun stehen wir ja immer noch vor dem Problem, dass wir dieses Programm jede Woche händisch ausführen müssten. Repetitive Aufgabe und so, ihr erinnert euch…

Aber kein Problem. Computer kommen heute mit on-board-Tools, die uns erlauben, solche Aufgaben zu automatisieren. Auf Unix-basierten Systemen, wie dem Mac, ist das z.B. Cron. Mit diesem Tool wollen wir nun dafür sorgen, dass unser Programm automatisch jeden Montag um 12:00 Uhr mittags ausgeführt wird.

Dazu gehen wir in die Konsole und geben folgendes ein:

crontab -e

Euer Standard-Texteditor öffnet sich. Bei mir ist das vi, wo wir nun ‚i‘ eingeben, um in den Insert-Modus zu gelangen. Dann geben wir das folgende ein:

0 12 * * 1 /Users/Jochen/opt/anaconda3/envs/Webscraper/bin/python /Users/Jochen/Desktop/Analysen_Skripts/Webscraper/webscraper.py

Mag komisch aussehen, ist aber so.

Der erste kryptische Teil, sagt unserem Cronjob, das wir den Job zu Minute 0 der zwölften Stunde an jedem Montag ausgeführt haben wollen (eine extrem hilfreiche Seite, um sich mit der Cron-Syntax vertraut zu machen, findet ihr hier).

Im zweiten Teil verweisen wir auf unser ‚virtual environment‘ und im dritten auf unser Programm. Achtet darauf, dass eure Pfade sicherlich andere sind als meine!

Dann schließen wir die Eingabe mit „Esc“ und geben „:wq“ ein. Dies schließt den Editor und, wenn alles korrekt eingegeben wurde, erhaltet ihr die Meldung „crontab: installing new crontab“.

Nun haben wir es tatsächlich geschafft!!!

Wir haben einen Web Scraper geschrieben, der uns eine Website nach Treffern mit unseren Suchparametern durchsucht und in einem einfach lesbaren Format abspeichert. Dieses Programm wird nun einmal die Woche automatisch ausgeführt. Wir haben damit also keine Arbeit mehr und zusätzliche Zeit für sinnvolle/-stiftende Tätigkeiten gewonnen 🙂

Habt viel Spaß beim Web Scrapen und Automatisieren!

Und natürlich, wie immer: Falls ihr Fragen, Anmerkungen, Ideen zu diesem Post habt, schreibt mir gerne eine Mail.


Avatar

Von Jochen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.