Die ultimative Anleitung zum Erstellen eines Web Scrapers mit Pyppeteer

Mihnea-Octavian Manolache am 28. Februar 2023

blog-image

Wenn es um Python und Web-Automatisierung geht, war Selenium so ziemlich das Go-to. Zumindest bis jetzt. Aufgrund des Erfolgs von Puppeteer in der JavaScript-Gemeinde begannen Python-Entwickler, sich mehr und mehr damit zu beschäftigen. Und so ist Pyppeteer entstanden. Aber was genau ist Pyppeteer? Und warum sollten wir es Selenium vorziehen? Ist es zuverlässig genug, um eine komplexe Lösung damit zu erstellen? Auf all diese Fragen und viele mehr werden wir im heutigen Artikel antworten. Mein Ziel für den heutigen Tag ist es, dass Sie, wenn Sie dieses Material durchlesen, zumindest mit einem gewissen Wissen nach Hause gehen sollten:

  • Eine Definition von Pyppeteer und seine Anwendungsfälle
  • Ein Verständnis dafür, wie Pyppeteer im Vergleich zu Selenium abschneidet
  • Eine aktuelle Implementierung eines Web Scrapers mit Pyppeteer

Machen Sie sich also bereit, denn heute werden wir reden und uns mit dem Programmieren beschäftigen!

Was ist Pyppeteer eigentlich und wie können Sie es nutzen?

Wenn Sie dies lesen, sind Sie wahrscheinlich bereits damit vertraut, was Web-Skripting im Allgemeinen ist. Und Sie haben wahrscheinlich schon von Puppeteer oder Selenium gehört, je nachdem, welche Programmiersprache Sie bevorzugen. Aber Pyppeteer ist in der Tat neu in der Szene des Web Scraping. Nun, um es kurz zu machen, Pyppeteer ist Puppeteer sehr viel ähnlicher als Selenium.

Puppeteer ist eine Node.js-Bibliothek, die die Steuerung einer Headless-Version von Chrome über das DevTools-Protokoll ermöglicht. Pyppeteer ist eine Python-Portierung von Puppeteer. Genau wie das Original Puppeteer ist Pyppeteer eine in Python geschriebene Bibliothek, die im Wesentlichen einen Browser automatisiert. Mit anderen Worten: Pyppeteer ist eine Python-Implementierung der Puppeteer-API, mit der Sie die Funktionen von Puppeteer in einer Python-Umgebung nutzen können. Der Hauptunterschied zwischen den beiden ist die verwendete Sprache.

Pyppeteer-Terminologie, die Sie kennen sollten

Bevor wir weitermachen, sollten wir einige Begriffe diskutieren, die im Zusammenhang mit Pyppeteer häufig verwendet werden:

  • Kopflos: Dies bedeutet, dass ein Browser ohne grafische Benutzeroberfläche (GUI) gestartet wird. Mit anderen Worten: Er läuft "hinter den Kulissen" und ist auf dem Bildschirm nicht zu sehen. Es wird normalerweise verwendet, um die Ressourcennutzung beim Scraping zu reduzieren.
  • Kopflastig: Ein "Headful"-Browser ist dagegen ein Browser, der mit einer grafischen Benutzeroberfläche läuft. Er ist das Gegenteil eines Headless-Browsers und wird häufig zum Testen, Debuggen oder für die manuelle Interaktion mit Webseiten verwendet.
  • Browser-Kontext: Dies ist ein Status, der von allen Seiten in einem Browser gemeinsam genutzt wird. Er wird normalerweise verwendet, um browserweite Einstellungen wie Cookies, HTTP-Header und Geolocation festzulegen.
  • DOM: Das Document Object Model (DOM) ist eine Programmierschnittstelle für HTML- und XML-Dokumente. Es stellt die Struktur einer Webseite in einem baumartigen Format dar, mit Knoten, die Elemente darstellen. Mit Pyppeteer können Sie mit den Elementen einer Seite interagieren, indem Sie das DOM manipulieren.
  • Elemente: Die Bausteine einer Web-Seite. Sie werden durch Tags, Attribute und Werte definiert.

Natürlich gibt es noch mehr, und Sie werden auf dem Weg dorthin noch einiges lernen. Aber ich wollte, dass Sie einen Überblick darüber bekommen, damit wir einen soliden Start haben. Ich bin überzeugt, dass die Kenntnis dieser Begriffe Ihnen helfen wird, das Wesentliche dieses Artikels besser zu verstehen.

Warum sollten Sie Pyppeteer für Ihr Scraping-Projekt verwenden?

Ich denke, es gibt zwei Aspekte in dieser Angelegenheit. Der erste ist, warum Pyppeteer eine gute Wahl für Web Scraping im Allgemeinen ist. Der zweite ist, warum Pyppeteer statt Selenium verwendet werden sollte. Im Allgemeinen sind einige der Vorteile von Pyppeteer für:

  • JavaScript auswerten: Pyppeteer bietet eine Funktion `page.evaluate()`. Damit können Sie JavaScript-Code im Kontext der Seite ausführen.
  • Netzsteuerung: Pyppeteer bietet eine `page.on()` Methode. Diese erlaubt es, auf Netzwerkereignisse, wie Anfragen und Antworten, die auf einer Seite passieren, zu hören.
  • Verfolgung und Protokollierung: Mit Pyppeteer können Sie die Aktivitäten des Browsers verfolgen und Browsermeldungen von einer Seite protokollieren. Dies erleichtert die Fehlersuche, das Tracing und das Verständnis der Aktivitäten einer Website.

Im Vergleich zu Selenium ist es recht ähnlich, da beide zur Automatisierung eines Webbrowsers verwendet werden. Es gibt jedoch ein paar wichtige Unterschiede und Vorteile, die Pyppeteer gegenüber Selenium hat:

  • Einfachheit: Pyppeteer hat eine einfachere und konsistentere API als Selenium, was die Nutzung für Anfänger erleichtert. Die Pyppeteer-API basiert auf dem DevTools-Protokoll, das dem Browser sehr ähnlich ist, und ist leicht zu erlernen und zu verwenden.
  • Leistung: Pyppeteer kann schneller sein als Selenium, weil es auf dem DevTools-Protokoll aufbaut. Das Protokoll wurde für das Debugging von Webseiten entwickelt und ist viel schneller als Selenium WebDriver.
  • Bessere Netzwerkkontrolle: Pyppeteer ermöglicht eine bessere Kontrolle über die Netzwerkeinstellungen des Browsers, wie z. B. das Abfangen von Anfragen und das Blockieren von Anfragen/Antworten. Dies erleichtert das Testen und Diagnostizieren von netzwerkbezogenen Problemen.

Und natürlich ist es auch eine Frage der Wahl. Nehmen Sie mich zum Beispiel. Ich programmiere tagtäglich in JavaScript. Und mit Puppeteer bin ich gut vertraut. Aber meine Lieblingsprogrammiersprache ist Python auf der anderen Seite. Wenn ich also einen Scraper mit einer bekannten Technologie in einer von mir bevorzugten Sprache bauen sollte, würde ich mich wahrscheinlich für Pyppeteer entscheiden.

Und damit haben wir, denke ich, die "Gesprächs"-Aspekte dieses Artikels abgedeckt. Es ist an der Zeit, mit der eigentlichen Codierung zu beginnen.

Wie man einen Web Scraper mit Pyppeteer erstellt

Bevor wir mit dem Programmieren beginnen, möchte ich Ihnen die offizielle Pyppeteer-Dokumentation vorstellen. Ich bin ein Verfechter der Verwendung der offiziellen Dokumentation, wann immer man sich festgefahren fühlt. Das heißt, bevor man Fragen in der Community stellt (z. B. auf Stackoverflow). Ich habe die Erfahrung gemacht, dass die meisten Antworten gefunden werden können, wenn man zuerst die Dokumentation liest. Nehmen Sie dies also als eine freundliche Bitte von mir. Wenn Sie nicht weiterkommen, lesen Sie die Dokumentation, suchen Sie dann nach Antworten und stellen Sie erst als letzten Ausweg Fragen.

#1: Einrichten der Umgebung

Das Wichtigste zuerst: Als Python-Entwickler sind Sie wahrscheinlich mit virtuellen Umgebungen vertraut. Das erste, was wir tun müssen, ist eine virtuelle Umgebung für unser Projekt zu erstellen. Im Allgemeinen verwende ich die folgende Befehlsfolge:

#

~ " mkdir py_project && cd py_project

# Erstellen der virtuellen Umgebung

~ " python3 -m venv env

# Aktivieren der virtuellen Umgebung

~ " source env/bin/activate

Was die virtuelle Umgebung anbelangt, so ist nun alles vorbereitet. Nun ist es an der Zeit, Pyppeteer zu installieren. Da Sie Ihr Terminal geöffnet haben, geben Sie einfach ein:

# Installieren Sie das Paket mit pip

~ " python3 -m pip install pyppeteer

# Öffnen Sie das Projekt in Ihrer IDE

~ " code .

#2: Einen einfachen Pyppeteer-Scraper erstellen

Mit dem letzten Befehl öffnen Sie Visual Studio Code oder Ihre bevorzugte IDE. Da Sie sich nun in der Entwicklungsumgebung befinden, lassen Sie uns eine neue `.py`-Datei erstellen, die unseren Code enthalten wird. Ich werde meine Datei `scraper.py` nennen. Beachten Sie, dass Pyppeteer von Haus aus asynchrone Ausführung unterstützt. Lassen Sie uns also sowohl `asyncio` als auch `pyppeteer` in unsere Datei importieren:

import asyncio
from pyppeteer import launch

Wenn das geschafft ist, können wir zu komplizierterem Code übergehen. Im Allgemeinen bin ich nicht der größte Verfechter der funktionalen Programmierung. Dennoch denke ich, dass die Aufteilung des Codes in kleine Teile ein besseres Lernen ermöglicht. Lassen Sie uns also unseren Code in eine Funktion einpacken:

async def scrape(url):

browser = await launch()

page = await browser.newPage()

await page.goto(url)

content = await page.content()

await browser.close()



return content

blog-image

Diese Funktion nimmt eine URL als Eingabe und startet einen Headless-Browser mit pyppeteer. Dann navigiert sie zu der angegebenen URL, ruft den Inhalt der Seite ab und schließt den Browser. Der zurückgegebene Wert ist nichts anderes als der von der Seite gesammelte HTML-Code. Mit dieser Funktion können Sie fast jede beliebige Website scrapen. Um die Funktion zu verwenden, rufen Sie sie in einer "Asyncio"-Ereignisschleife auf, etwa so:

async def main():

content = await scrape('https://www.example.com')

print(content)

loop = asyncio.get_event_loop()

loop.run_until_complete(main())

#Nr. 3: Mehr Funktionen hinzufügen

Bis zu diesem Punkt haben wir einen funktionierenden Abstreifer. Aber das ist so ziemlich alles, was wir haben. Wenn Sie einen fortschrittlicheren Web Scraper mit Pyppeteer bauen wollen, müssen Sie mehr Funktionalität zu id hinzufügen. Spoiler-Alarm: Wir werden in die Welt der objektorientierten Programmierung eintauchen. Aber lassen Sie uns zunächst unsere Ziele verfolgen. Was soll unser Scraper können?

  1. Initialisieren des Browsers mit einigen benutzerdefinierten Werten
  2. Navigieren und Extrahieren von Inhalten aus einer Webseite
  3. Text in ein Eingabefeld schreiben
  4. Den Wert eines einzelnen Elements extrahieren
  5. Wert aus mehreren Elementen extrahieren

3.1. Benutzerdefinierte Optionen

Lassen Sie uns also erst einmal eine neue Klasse "Scraper" erstellen, deren Methoden wir später hinzufügen werden:

class Scraper:

def __init__(self, launch_options: dict) -> None:

self.options = launch_options['options']

self.viewPort = launch_options['viewPort'] if 'viewPort' in launch_options else None

pass

Das einzige Argument, das wir für unseren Scraper verwenden, ist ein `launch_options`-Wörterbuch. Wie Sie sehen, enthält es zwei Schlüssel. Ein Schlüssel definiert die Startoptionen von Pyppeteer. Die zweite Option ist entweder `None` oder ein Wörterbuch, das die `width` und `height` des `viewPort` enthält. Letzteres wird für diese Methode verwendet.

3.2. Zu einer Seite navigieren

Wenn Sie sich die Funktion ansehen, die wir zuvor verwendet haben, werden Sie sehen, dass wir sowohl das Navigieren als auch das Extrahieren von Rohdaten aus einer bestimmten URL abdecken. Das Einzige, was wir tun müssen, ist, die Funktion zu optimieren und in eine Methode für unseren Scraper zu verwandeln:

async def goto(self, url: str) -> None:

self.browser = await launch(options=self.options)

self.page = await self.browser.newPage()

await self.page.setViewport(self.viewPort) if self.viewPort != None else print('[i] Using default viewport')

await self.page.goto(url)

Diese Methode ist recht einfach. Zuerst wird ein neuer Browser gestartet, mit den benutzerdefinierten Optionen, die wir zuvor festgelegt haben. Dann wird eine neue Seite erstellt und, wenn unser `launch_options` Wörterbuch `viewPort` enthält, wird der viewPort der Seite gesetzt. Andernfalls wird eine einfache Meldung protokolliert. Zu guter Letzt führt es uns zum Ziel.

3.3. Extrahieren von Rohdaten aus einer Seite

Wieder haben wir die Methode in unserer anfänglichen "Scraper"-Funktion. Wir werden nur darauf warten, dass der "page.content()" geladen wird und seinen Wert zurückgibt:

async def get_full_content(self) -> str:

content = await self.page.content()

return content

3.4. Text in ein Eingabefeld schreiben

Um mit Pyppeteer etwas in ein Eingabefeld zu schreiben, benötigen Sie zwei Dinge. Erstens muss das Element gefunden werden. Zweitens muss man ihm einen Wert hinzufügen. Glücklicherweise hat Pyppeteer Methoden für diese beiden Aktionen:

async def type_value(self, selector: str, value: str) -> None:

element = await self.page.querySelector(selector)

await element.type(value)

3.5. Wert von Seite extrahieren

Denken Sie daran, dass wir in der Lage sein wollen, entweder den Wert aus einem einzelnen Element oder Werte aus mehreren Elementen zu extrahieren. Wir könnten eine einzige Methode für beides verwenden. Aber ich mag es normalerweise, wenn die Dinge getrennt sind. Deshalb füge ich jetzt zwei weitere Methoden hinzu:

async def extract_one(self, selector) -> str:

element = await self.page.querySelector(selector)

text = await element.getProperty("textContent")

return await text.jsonValue()

Hier suchen wir das Element mit der Methode "querySelector". Dann warten wir auf den "textContent" und geben seinen "jsonValue()" zurück. Wenn wir hingegen viele Elemente auswählen wollen, verwenden wir "querySelector":

async def extract_many(self, selector) -> list:

result = []

elements = await self.page.querySelectorAll(selector)

for element in elements:

text = await element.getProperty("textContent")

result.append(await text.jsonValue())

return result

Diese Methode funktioniert ähnlich wie `extract_one`. Der einzige Unterschied ist ihr Rückgabewert. Dieses Mal geben wir eine Liste aller Texte innerhalb der ausgewählten Elemente zurück. Und ich denke, damit haben wir alle unsere Ziele erreicht.

#Nr. 4: Unsichtbar machen

Beim Web-Scraping kann Stealthiness als die Fähigkeit beschrieben werden, unentdeckt zu bleiben. Natürlich erfordert die Entwicklung eines völlig unentdeckbaren Scrapers eine Menge Arbeit. Der Stealth-Modus der Web Scraping API wird zum Beispiel von einem engagierten Team gepflegt. Und der Aufwand, der darin steckt, macht den Fingerabdruck unseres Scrapers bei jeder Anfrage einzigartig.

Aber mein übergeordnetes Ziel für dieses Tutorial ist es, Sie auf den richtigen Weg zu bringen. Und der richtige Weg für einen kompletten Web Scraper mit Pyppeteer beinhaltet das Hinzufügen einiger Stealth-Funktionen. Glücklicherweise gibt es, genau wie `puppeteer-extra-plugin-stealth` in Node, auch ein Paket für Python. Und es heißt intuitiv `pyppeteer-stealth`. Um es zu Ihrem Projekt hinzuzufügen, installieren Sie es zunächst mit pip:

~ " python3 -m pip install pyppeteer_stealth

Importieren Sie es dann in Ihr Projekt und fügen Sie einfach eine zusätzliche Codezeile hinzu:

async def goto(self, url: str) -> None:

self.browser = await launch(options=self.options)

self.page = await self.browser.newPage()

# Stealth machen

await stealth(self.page)

await self.page.setViewport(self.viewPort) if self.viewPort != None else print('[i] Using default viewport')

await self.page.goto(url)

Und hier sehen Sie, wie Sie Ihren Scraper ausführen. Ich habe dem Code einige Kommentare hinzugefügt, um hervorzuheben, was die einzelnen Schritte bewirken:

async def main():

# Define the launch options dictionary

launch_options = {

'options': {

'headless': False,

'autoClose': True

},

'viewPort': {

'width': 1600,

'height': 900

}

}

# Initialize a new scraper

scraper = Scraper(launch_options)

# Navigae to your target

await scraper.goto('https://russmaxdesign.github.io/accessible-forms/accessible-name-input01.html')

# Type `This is me` inside the input field

await scraper.type_value(

'#fish',

'This is me')

# Scrape the entire page

content = await scraper.get_full_content()

print(content)

# Scrape one single element

el = await scraper.extract_one('body > div:nth-child(14) > ul')

print(el)

# Scrape multiple elements

els = await scraper.extract_many('p')

print(els)

loop = asyncio.get_event_loop()

loop.run_until_complete(main())

Schlussfolgerung

Pyppeteer ist ein erstaunliches Werkzeug für Web Scraping. Es portiert die gesamte Puppeteer-API nach Python und ermöglicht es der Python-Gemeinschaft, diese Technologie zu nutzen, ohne JavaScript lernen zu müssen. Ich glaube nicht, dass es ein Ersatz für Selenium ist, aber es ist sicher eine gute Alternative zu Selenium.

Ich hoffe, dass der heutige Artikel einen Mehrwert für Ihren Lernweg darstellt. Und da ich gerne die Grenzen jedes Einzelnen ausreizen möchte, fordere ich Sie auf, das heute Gelernte zu erweitern. Der Scraper, den wir gemeinsam gebaut haben, ist ein wirklich guter Ausgangspunkt und führt in ein Schlüsselelement der Programmierung ein: OOP. Ich fordere euch also auf, dem `Scraper` weitere Methoden hinzuzufügen und ihn wirklich erstaunlich zu machen.

Nachrichten und Aktualisierungen

Bleiben Sie auf dem Laufenden mit den neuesten Web Scraping-Anleitungen und Nachrichten, indem Sie unseren Newsletter abonnieren.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Ähnliche Artikel

Vorschaubild
LeitfädenSERP Scraping API - Startanleitung

Sammeln Sie mühelos Echtzeitdaten von Suchmaschinen mit der SERP Scraping API. Verbessern Sie Marktanalysen, SEO und Themenforschung mit Leichtigkeit. Legen Sie noch heute los!

WebscrapingAPI
Autorenavatar
WebscrapingAPI
7 Minuten lesen
Vorschaubild
LeitfädenWie man Amazon-Produktdaten scrappt: Ein umfassender Leitfaden zu Best Practices & Tools

Entdecken Sie die Komplexität des Scrapens von Amazon-Produktdaten mit unserem ausführlichen Leitfaden. Von Best Practices und Tools wie der Amazon Scraper API bis hin zu rechtlichen Aspekten erfahren Sie, wie Sie Herausforderungen meistern, CAPTCHAs umgehen und effizient wertvolle Erkenntnisse gewinnen.

Suciu Dan
Autorenavatar
Suciu Dan
15 Minuten lesen
Vorschaubild
LeitfädenErfahren Sie, wie Sie die Cloudflare-Erkennung mit dem besten Selenium-Browser umgehen

Erfahren Sie, welcher Browser am besten geeignet ist, um Cloudflare-Erkennungssysteme beim Web-Scraping mit Selenium zu umgehen.

Mihnea-Octavian Manolache
Autorenavatar
Mihnea-Octavian Manolache
9 Minuten lesen