Das Problem
Eine der Aufgaben, für die ich regelmäßig beauftragt werde, ist die Erstellung von Mailinglisten. Das ist eine Arbeit, die sehr monoton und zeitraubend werden kann, wenn man sie händisch ausführt. Meistens kopiert man mit STRG+C und STRG+V die gesuchten Kontakt-Informationen aus dem Webbrowser in die richtigen Spalten und Zeilen einer Excel-Tabelle: Name der Organisation, Straße, Hausnummer, Postleitzahl, Ort, Email-Adresse, Telefonnummer… Das setzt allerdings voraus, dass man die richtige Webseite mit allen gesuchten Informationen bereits gefunden hat. Diese Suche kann selbst zeitraubend und anstrengend werden, etwa wenn man nicht weiß, welcher Rechercheweg am effizientesten zum Ziel führt, welche Schlagworte man am besten in die Suchmaschine eingeben sollte. Je nach Zielgruppe führt eine Google-Anfrage ins Leere, und man muss anfangen kreativ zu werden.
Gibt es aber einen gleichbleibenden Rechercheweg, kann man die Informationssuche automatisieren. Eine zentrale Methode hierfür ist Webscraping (auch: Screenscraping, https://de.wikipedia.org/wiki/Screen_Scraping) zum automatischen Extrahieren von Daten, insbesondere aus Texten in Webbrowsern. Python bietet hierfür einige sehr nützliche Packages, vor allem BeautifulSoup, Scrapy und Selenium. BeautifulSoup nutze ich am häufigsten, Scrapy eher selten. Beide eignen sich hervorragend für statische Websites; Selenium ist die Wahl bei dynamischen Inhalten. Das Problem mit Selenium ist jedoch, dass es recht langsam ist. Deshalb gehe ich meist so vor, dass ich Selenium nur bei Seiten nutze, bei denen das Scraping mit den anderen beiden erfolglos war.
Eine zweischrittige Methode
In der Regel arbeite ich in zwei Schritten. Im ersten Schritt erstelle ich eine Liste aus den Namen der Organisationen und Links zu ihren Homepages; im zweiten Schritt loope ich durch diese Liste und lasse die Scraper die gesuchte Informationen finden. Damit sie nicht jedesmal die ganze Webseite absuchen müssen (was je nach Größe bzw. Tiefe der Seite viel Zeit braucht), grenze ich die Links durch Schlagworte ein, wie z.B. „Ansprechpartner“, „Kontakt“ und „Impressum“, die eine hohe Wahrscheinlichkeit haben, dass dort die gesuchte Kontaktinformation stehen wird. Mit dieser Methode habe ich u.a. einmal einen Verteiler mit Email-Adressen aller aktueller Bürgermeister*innen Deutschlands generiert.

Das Problem: Es gibt in Deutschland mehr als 10.000 Gemeinden, und ebenso viele Kontakte und Adressen enthält die Liste. Die Adressen habe ich dabei mithilfe von Wikipedia gescrapt, die Emails dagegen mithilfe von BeautifulSoup und Requests (und Regular Expressions) von den Homepages der Gemeinden.

Nach einer Versendungsaktion an etwa 4.500 Gemeinden aus dieser Liste hatten wir nur 31 Rückläufer, was einer Fehlerquote von weit unter 1% (ca. 0,69%) entspricht. Vor allem ist dieses Vorgehensweise extrem zeit- und ressourcensparend. Vorher mussten hierfür mehrere Mitarbeiter*innen für mehrere Stunden abbestellt werden; nun kann ich diese Arbeit weitgehend alleine in einigen Stunden bis zu wenigen Arbeitstagen vollrichten, auch bei mehreren Tausend Kontakten.
Lediglich bei der Qualitätskontrolle ist hilfreich, wenn jemand anderes die aus der CSV generierte Excel-Datei nochmals kritisch durchsieht. Eine manuelle Nachbesserung ist hier und da noch nötig, doch können systematische Fehler in der Regel mithilfe eines Skripts automatisch bereinigt werden. Das gilt auch für bestimmte Datenergänzungen. So konnte aus der Funktionsbezeichnung das Geschlecht und die richtige Anrede entnommen werden, da diese gegendert waren, wie z.B. bei „Bürgermeisterin“ und „Bürgermeister“. Die Endung -in konnte durch Regular Expressions als weibliche Markierung erkannt werden, sodass Python automatisch das Geschlecht und die richtige Anrede („Frau“) in einer neuen Spalte ergänzen konnte. Daraus konnte man wiederum eine generische Briefanrede erzeugen: „Sehr geehrte Frau Bürgermeisterin,“. Nur diese kleinen Ergänzungen hätten, wollte man sie händisch eintragen, bei einer Liste von mehreren Tausend Einträgen Stunden gedauert.

Fazit: eine enorme Zeitersparnis
Der Zeitaufwand der manuellen Dateneingabe hatte ich einmal auch ungefähr geschätzt. Im Durchschnitt brauchte man für das Anlegen eines Datensatzes im Durchschnitt 5-10 Minuten, je nach Aufwand. Für das Gesamtgemeindeverzeichnis Deutschlands (derzeit 10.796 Gemeinden) hätte man also im Best Case 899,67 Stunden gebraucht. Setzt man 142 Stunden für einen Personenmonat an, so wären das 6,33 Personenmonate. Im Worst Case müsste man dagegen 1794,83 Stunden bzw. 12,64 Personenmonate planen. Anders gesagt: nur für diese Verteilerliste könnte man einen Mitarbeiter ein ganzes Jahr beschäftigen (und selbst dann wäre nicht garantiert, dass er oder sie damit fertig würde). Dazu kommt jedoch, dass sich die Kontakte ständig ändern (wegen Wahlen, Rücktritten, Todesfällen und dergleichen). Insofern wäre die Arbeit für eine einzelne Person kaum zu bewältigen.