Zurück zum Blog
Anleitungen
Mihnea-Octavian ManolacheLast updated on Mar 31, 202610 min read

So führen Sie einen Headless-Browser mit Python für das Web-Scraping aus: Tipps und Tricks

So führen Sie einen Headless-Browser mit Python für das Web-Scraping aus: Tipps und Tricks

Die Verwendung eines Headless-Browsers in Python mit Selenium ist beim Web-Scraping fast schon Standard. Aber was ist eigentlich ein Headless-Browser? Und welcher Headless-Browser eignet sich am besten für Selenium? Und warum sollte man in Python überhaupt einen Headless-Browser verwenden, wenn es doch `requests` gibt? Nun, zu diesem Thema gibt es viele Fragen. Das bedeutet, dass wir gemeinsam viele Antworten darauf finden werden. Bevor wir jedoch tiefer in die Materie einsteigen, wollen wir uns zunächst einige Lernziele vor Augen führen. Am Ende dieses Artikels sollten Sie in der Lage sein:

  • Verstehen, was ein Headless-Browser ist und welche Anwendungsfälle es gibt
  • zu wissen, wie man einen Headless-Browser in Python öffnet
  • einen Web-Scraper mit Python und Selenium erstellen

Und schließlich werden wir auch über Alternativen zu Python-Headless-Browsern sprechen. Auch wenn der Fokus auf Python liegt, ist es mein Ziel, die beste Scraping-Lösung zu finden. Dabei spielen Reaktionszeit, Ressourcenverbrauch usw. eine Rolle. Also, ohne weitere Umschweife, lassen Sie uns gleich in das Thema einsteigen!

Was bedeutet „Python-Headless-Browser“?

Allgemein gesagt ist ein Browser ein Computerprogramm, das es Benutzern ermöglicht, auf einer Webseite zu navigieren und mit ihr zu interagieren. Ein Headless-Browser ist genau das, jedoch ohne grafische Benutzeroberfläche. Das bedeutet, dass ein Python-Headless-Browser ein Programm ist, das Folgendes kann:

  • zu jeder beliebigen Website im Internet navigieren
  • JavaScript-Dateien rendern, die von der Website bereitgestellt werden
  • mit den Komponenten dieser Webseite interagieren

Da keine grafische Benutzeroberfläche vorhanden ist, stellen sich einige Fragen zur Interaktion. Die Antwort ist jedoch recht einfach: Da es keine GUI gibt, können Menschen nicht direkt mit der Seite interagieren. Und genau hier kommen Web-Treiber ins Spiel. Ein Web-Treiber ist eine Schnittstelle, die Introspektion und Steuerung ermöglicht. Einfach ausgedrückt sind Web-Treiber Frameworks, mit denen wir verschiedene Webbrowser programmgesteuert steuern können.

Es gibt einige Frameworks, die die Browser-Automatisierung in Python ermöglichen. Das wichtigste davon ist jedoch Selenium. Selenium ist eine Suite von Tools, die in erster Linie für automatisierte Tests entwickelt wurde. In der Praxis wird es jedoch auch häufig für das Web-Scraping verwendet.

Warum einen Headless-Browser in Python verwenden?

Laut der Kopfzeile auf der Startseite von Selenium:

„Selenium automatisiert Browser. Das ist alles! Was Sie mit dieser Leistungsfähigkeit anstellen, liegt ganz bei Ihnen.“

Dies lässt vermuten, dass automatisierte Browser vielfältige Anwendungsfälle haben. Aber warum sollte man sie im Headless-Modus ausführen? Nun, die Antwort ist wieder einmal einfach. Ein Python-Headless-Browser verbraucht im Vergleich zu einem Headful-Browser weniger Ressourcen (CPU und Arbeitsspeicher). Und das liegt vor allem daran, dass keine grafischen Elemente gerendert werden müssen.

Auch hier gilt: Weniger ist immer noch mehr, verglichen mit einem einfachen HTTP-Client wie beispielsweise Pythons `requests`. Und das liegt daran, dass der Headless-Browser immer noch viele Prozesse öffnet, um mit der Seite zu interagieren und JavaScript-Dateien zu rendern. Wie du weißt, kann `requests` kein JavaScript rendern. Du kannst damit nur rohen HTML-Code abrufen. Und heutzutage reicht das für Web-Scraping bei weitem nicht aus. Die meisten modernen Webplattformen sind stark auf JavaScript angewiesen, um das DOM zu füllen. Wenn Sie beispielsweise versuchen, eine React-App mit `curl` abzurufen, erhalten Sie eine leere Webseite, die Sie auffordert, „JavaScript zu aktivieren“:

<!doctype html>

<html lang="en">

  <head>

 	...

  </head>

  <body>

 	<noscript> You need to enable JavaScript to run this app. </noscript>

 	<div id="root"></div>

  </body>

</html>

Während dies mit `requests` nicht möglich ist, lässt es sich mit einem Headless-Browser bewerkstelligen. Und damit ist eine unserer anfänglichen Fragen beantwortet. Moderne Web-Scraper verwenden Headless-Browser anstelle von `requests`, da die Antwort andernfalls unvollständig wäre.

Was sind die Nachteile eines Headless-Browsers?

Der Hauptnachteil eines Python-Headless-Browsers (und fast aller automatisierten Browser) ist sein Fingerabdruck. Wenn du meine Artikel verfolgst, weißt du, dass ich manchmal von „Stealthiness“ spreche. Das ist die Fähigkeit eines automatisierten Browsers, unentdeckt zu bleiben.

Und in Python sind Headless-Browser leicht zu erkennen. Zunächst einmal verrät die Überprüfung einer einfachen Eigenschaft des Browsers wie `navigator.webdriver` sofort, ob ein Browser von einem Web-Driver gesteuert wird. Beim Web-Scraping besteht eine der größten Herausforderungen darin, Wege zu finden, um eine Erkennung zu vermeiden. Wir nennen diese Methoden oder Techniken „Evasion“. Mehr dazu kannst du hier lesen.

Bei Web Scraping API beispielsweise haben wir ein engagiertes Team, das ständig an unserem Stealth-Modus arbeitet. Damit soll sichergestellt werden, dass der Fingerabdruck unseres Browsers bei jeder Anfrage einzigartig und nicht nachweisbar ist.

Headless-Browser, die mit Python Selenium verfügbar sind

Zunächst einmal sollten Sie wissen, dass Selenium sehr leistungsstark ist. Und es ist nicht einmal auf Python beschränkt. Es gibt Selenium-Clients und Web-Treiber für C#, Ruby, Java, Python und sogar JavaScript. Und die Unterstützung durch den Selenium-Web-Treiber ist noch beeindruckender. Er unterstützt alle gängigen Browser:

In der Welt des Web-Scrapings sind Chrome und Firefox die am häufigsten verwendeten Headless-Browser für Python. Ich denke, das liegt vor allem daran, dass diese beiden Browser sowohl leistungsstark als auch plattformübergreifend sind. Sie können beispielsweise Ihr Web-Scraping-Projekt in einer MacOS-Umgebung entwickeln und es dann problemlos unter Linux bereitstellen.

So öffnen Sie einen Headless-Browser in Python

Nachdem wir nun einige theoretische Konzepte behandelt haben, können wir uns getrost dem praktischen Teil zuwenden. In diesem Abschnitt zeige ich Ihnen, wie Sie mit Selenium einen Web-Scraper erstellen. Stellen Sie für dieses Projekt sicher, dass auf Ihrem Rechner Python und Chrome installiert sind.

#1: Die Umgebung einrichten

Wie üblich sollten wir in Python alles in einer virtuellen Umgebung kapseln. Wenn Sie mit virtuellen Umgebungen nicht vertraut sind, lesen Sie bitte zuerst diesen Artikel. Öffnen wir nun ein neues Terminalfenster und gehen wir wie folgt vor:

  • Einen neuen Ordner erstellen
  • Navigieren Sie zu dem Ordner
  • Eine neue virtuelle Umgebung erstellen
  • Die virtuelle Umgebung aktivieren

~ mkdir headless_scraper

~ cd headless_scraper

~ python3 -m venv env

~ source env/bin/activate

#2: Abhängigkeiten installieren

Es ist ziemlich klar, dass wir für unser Projekt Selenium und einen Web-Driver benötigen. Glücklicherweise können wir beides mit Pythons Paketmanager `pip` installieren. Geben Sie im selben Terminalfenster den folgenden Befehl ein:

~ pip install selenium webdriver-manager

Jetzt sind Sie bestens für den Erfolg gerüstet! Wir können mit dem eigentlichen Programmieren fortfahren. Kurzer Hinweis: Dieser Artikel konzentriert sich auf die Interaktion mit einem Headless-Browser. Eine vollständige Web-Scraping-Lösung erfordert viel mehr Aufwand. Aber ich bin sicher, wenn Sie unseren Blog-Beiträgen folgen, können Sie das in kürzester Zeit hinbekommen.

#3: Einen automatisierten Browser öffnen

Bisher haben wir das Projekt, aber es gibt keine Datei, die wir ausführen können. Erstellen wir eine neue `.py`-Datei und öffnen wir sie in unserer IDE:

~ touch headles_scraper.py

~ code .

Sie sollten sich nun in Visual Studio Code oder Ihrer IDE befinden. Beginnen Sie damit, die erforderlichen Pakete in `handle_scraper.py` zu importieren:

from selenium import webdriver

from webdriver_manager.chrome import ChromeDriverManager

Letzteres ist ein Paket, das Ihnen hilft, Web-Treiber für die verschiedenen von Selenium unterstützten Browser einfach zu verwalten. Mehr darüber erfahren Sie hier. Als Nächstes möchten wir mit Selenium einen neuen Browser erstellen und eine Website öffnen:

driver = webdriver.Chrome(ChromeDriverManager().install())

driver.get('https://webscrapingapi.com')

Führen Sie diese Datei jetzt aus, und Sie werden sehen, dass es funktioniert. Anstatt jedoch einen Python-Headless-Browser zu verwenden, öffnet sich ein Chrome-Fenster mit Benutzeroberfläche:

#4: Headless-Modus

Wir haben uns vorgenommen, einen ressourcenschonenden Web-Scraper zu erstellen. Idealerweise möchten wir also mit Selenium einen Headless-Browser öffnen. Glücklicherweise gibt es eine einfache Methode, mit der wir Selenium von Headful auf Headless umstellen können. Wir müssen lediglich die Optionen des Chrome-Web-Drivers nutzen. Importieren wir also `Options` und fügen zwei weitere Codezeilen hinzu:

...

from selenium.webdriver.chrome.options import Options

...

options = Options()

options.headless = True

driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)

driver.get('https://webscrapingapi.com')

Führe dein Skript erneut aus. Wie du sehen kannst, erscheint diesmal kein Fenster. Aber läuft es wirklich im Hintergrund? Eine schnelle Möglichkeit, dies zu visualisieren und zu überprüfen, ist ein Screenshot mit Selenium. Füge einfach diese Zeile am Ende deines Skripts ein:

driver.get_screenshot_as_file('headless.png')

Wenn alles geklappt hat, solltest du dasselbe Bild wie ich sehen:

#5: Scraping-Funktionen hinzufügen

Was ist ein Web-Scraper? Im Kern ist ein Web-Scraper ein Programm, das einen Endpunkt auf einem Server aufruft und Daten von diesem sammelt. Bei Websites bestehen diese Daten in der Regel aus HTML-Dateien. Aber bestimmte Server liefern heutzutage auch JSON-Objekte. Bleiben wir also bei diesem Begriff: Daten. Für den folgenden Abschnitt setzen wir uns höhere Ziele. Nutzen wir etwas objektorientierte Programmierung! Unsere Ziele sind:

  • Erstellen einer Scraper-Klasse
  • Eine Methode zum Extrahieren von Rohdaten hinzufügen
  • Eine Methode zum Extrahieren von Daten aus einem einzelnen Element hinzufügen
  • Eine Methode zum Extrahieren von Daten aus Elementen derselben Klasse hinzufügen

Wir haben also drei grundlegende Methoden, die wir erstellen wollen. Doch zu Lernzwecken eröffnen diese drei Methoden nicht nur einen Weg zum Web-Scraping, sondern auch zur OOP mit Python. Und ich finde das ziemlich cool! Löschen wir nun alles, was wir bisher programmiert haben, und fangen ganz von vorne an:

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

from selenium.webdriver.common.by import By

from selenium.webdriver.remote.webelement import WebElement

class Scraper:

   def __init__(self, headless: bool = True) -> None:

       self.headless = headless

       pass

   def setup_scraper(self) -> None:

       self.options = Options()

       self.options.headless = self.headless

       self.driver = webdriver.Chrome(options=self.options)

   def navigate(self, target) -> None:

       self.driver.get(target) if target else print('[!] No target given. Please specify a URL.')

   def extract_raw_data(self) -> str:

       return self.driver.page_source

   def extract_single_element(self,  selector: str, selector_type: By = By.CSS_SELECTOR) -> WebElement:

      return self.driver.find_element(selector_type, selector)

  

   def extract_all_elements(self, selector: str, selector_type: By = By.CSS_SELECTOR) -> list[WebElement]:

       return self.driver.find_elements(selector_type, selector)

Ich habe Typangaben hinzugefügt, um das Verständnis zu erleichtern, nicht um die Leistung zu verbessern. Auf diese Weise kannst du dir die App aus einer I/O-Perspektive vorstellen. Nun sind die Methoden ziemlich selbsterklärend. Wir führen keinerlei Aktionen an den Daten durch, wir geben sie lediglich zurück. Wenn du möchtest, kann das ein Ausgangspunkt für dich sein, um einen komplexen Scraper mit einem Python-Headless-Browser zu erstellen.

Bisher bewirkt die Ausführung der Datei noch nichts. Das liegt daran, dass wir unseren Scraper und seine Methoden lediglich deklariert haben. Wir müssen sie nun verwenden. Fügen wir also die folgenden Codezeilen hinzu:

# Initialize a new Scraper and navigate to a target

scraper = Scraper()

scraper.setup_scraper()

scraper.navigate('https://httpbin.org')

# Extract and print the entire HTML document

raw_data = scraper.extract_raw_data()

print(raw_data)

# Extract and print an element by its class name

single_element = scraper.extract_single_element('title', By.CLASS_NAME)

print(single_element.text)

# Extract and print all elements belonging to a tag type

all_elements = scraper.extract_all_elements('a', By.TAG_NAME)

print([el.get_attribute('href') for el in all_elements])

Und das war’s schon. Wenn du dein Skript jetzt ausführst, wirst du sehen, dass etwas passiert. Auch dies ist lediglich ein Prototyp, der dir den Einstieg erleichtern soll. Wenn du mehr darüber erfahren möchtest, wie ein Python-Headless-Browser beim Web-Scraping eingesetzt werden kann, fordere ich dich auf:

Auf diese Weise erwerben Sie nicht nur Wissen, sondern können auch ein Projekt zu Ihrem Portfolio hinzufügen.

Was sind die besten Alternativen zu Python-Headless-Browsern?

Python ist eine der beliebtesten Programmiersprachen für die Entwicklung von Web-Scrapern. Doch es ist nicht die einzige Lösung. Und es ist auch nicht die beste! In diesem Abschnitt besprechen wir Alternativen zu einem Python-Headless-Browser. Wir beginnen damit, warum man sich nach alternativen Lösungen umsehen sollte, und betrachten auch konkrete Beispiele.

Der Hauptgrund, warum Sie sich für eine Alternative zum selbstständigen Erstellen eines Python-Webscrapers entscheiden würden, sind die Ressourcen. Eine vollständige Webscraping-Lösung erfordert die Implementierung eines IP-Rotationssystems, einiger Umgehungstechniken und die Berücksichtigung der Performance, um nur einige Punkte zu nennen. Die Erstellung eines Webscrapers ist also nicht nur teuer, sondern auch zeitaufwendig. Ganz zu schweigen davon, dass die Wartung der Infrastruktur noch weitere Kosten verursacht.

Der zweite Nachteil des Python-Headless-Browsers hängt mit der Leistung zusammen. Python ist zwar eine großartige Sprache und sehr benutzerfreundlich, aber nicht gerade für seine Geschwindigkeit bekannt. Im Gegensatz zu beispielsweise Java (das ebenfalls über ein Selenium-Paket verfügt) ist Python sowohl dynamisch typisiert als auch interpretiert. Diese beiden Eigenschaften machen es im Vergleich zu anderen Sprachen deutlich langsamer. Nachdem wir nun ein allgemeines Verständnis haben, wollen wir ins Detail gehen. Hier sind die 5 besten Alternativen zu Selenium und dem Python-Headless-Browser:

#1: Web-Scraping-API

Wenn Sie den ersten von uns identifizierten Nachteil beheben möchten, sollten Sie sich nach Scraping-Anbietern von Drittanbietern umsehen. Und die Web Scraping API bietet eine komplette Scraping-Suite. Außerdem ist unser Service vollgepackt mit Funktionen wie:

  • IP-Rotationssystem für Rechenzentrums- und Residential-Proxys
  • Stealth-Modus
  • Captcha-Löser

Allein diese drei Funktionen machen es für ein Ziel nahezu unmöglich, unseren Scraper zu erkennen und zu blockieren. Hinzu kommen die Scraping-Funktionen. Mit der Web-Scraping-API können Sie Daten anhand von Selektoren extrahieren, zwischen Gerätetypen wechseln, Screenshots erstellen und vieles mehr. Eine vollständige Liste der Funktionen finden Sie hier.

#2: Puppeteer

Puppeteer ist das Pendant zu Selenium für JavaScript. Es ist eine der am häufigsten verwendeten Bibliotheken für die Web-Automatisierung. Im Gegensatz zu Selenium ist der Standardzustand von Puppeteer „headless“. Sie müssen also keinen zusätzlichen Code hinzufügen, um es „headless“ zu machen. Noch interessanter ist, dass es auch eine Implementierung der Puppeteer-API für Python gibt. In diesem Blogbeitrag gehe ich ausführlich auf die Erstellung eines Web-Scrapers mit Puppeteer ein.

#3: Playwright

Playwright ist ein weiteres Web-Automatisierungstool, das von Microsoft-Mitwirkenden entwickelt wurde. Es ist vor allem deshalb beliebt, weil es Unterstützung für verschiedene Sprachen und Plattformen bietet. Ihr Motto lautet tatsächlich „Jeder Browser, jede Plattform“. Auf ihre API kann von jedem Betriebssystem und mit jeder der folgenden Sprachen zugegriffen werden:

Dies sind die wichtigsten Alternativen zu einem Python-Headless-Browser. Es gibt jedoch auch noch andere Tools. ZombieJS oder HtmlUnit sind nur zwei weitere aus einer langen Liste. Ich denke, die Wahl einer Technologie ist sowohl eine Frage der Leistung als auch der persönlichen Vorlieben. Daher empfehle ich dir, sie alle zu testen und deinen Favoriten auszuwählen.

Fazit

Die Verwendung eines Python-Headless-Browsers hat Vor- und Nachteile. Einerseits können Sie eine maßgeschneiderte Lösung entwickeln, die Sie jederzeit um weitere Funktionen erweitern können. Andererseits können Entwicklung und Wartung recht kostspielig sein. Und dann ist da noch das Problem der Unauffälligkeit. Wenn Sie eine professionelle Lösung benötigen, halte ich es für das Beste, sich an einen Drittanbieter zu wenden. Ansonsten werde ich Ihnen zu Lernzwecken immer empfehlen, mit der Technologie zu experimentieren.

Über den Autor
Mihnea-Octavian Manolache, Full-Stack-Entwickler @ WebScrapingAPI
Mihnea-Octavian ManolacheFull-Stack-Entwickler

Mihnea-Octavian Manolache ist Full-Stack- und DevOps-Entwickler bei WebScrapingAPI. Er entwickelt Produktfunktionen und sorgt für die Wartung der Infrastruktur, die den reibungslosen Betrieb der Plattform gewährleistet.

Los geht’s

Sind Sie bereit, Ihre Datenerfassung zu erweitern?

Schließen Sie sich den über 2.000 Unternehmen an, die WebScrapingAPI nutzen, um Webdaten im Unternehmensmaßstab ohne zusätzlichen Infrastrukturaufwand zu extrahieren.