Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

Web-Scraping mit Selenium Wire in Python

Promo

Dieser Leitfaden erklärt, wie Sie Selenium Wire für Web-Scraping verwenden, und behandelt Themen wie Anfrage-Interception und dynamische Proxy-Rotation.

What Is Selenium Wire?

Selenium Wire ist eine Erweiterung für die Python-Bindings von Selenium, die Kontrolle über Browser-Anfragen bereitstellt. Sie ermöglicht das Abfangen und Modifizieren von Anfragen und Antworten in Echtzeit direkt aus Ihrem Python-Code, während Sie Selenium verwenden.

Hinweis:
Die Library wird nicht mehr gepflegt, jedoch verwenden mehrere Scraping-Technologien und Skripte sie weiterhin.

Why Use Selenium Wire?

Browser haben bestimmte Einschränkungen, die Web-Scraping erschweren können. Zum Beispiel ermöglichen sie es Ihnen nicht, autorisierte Proxy-URLs zu setzen oder rotate proxies im laufenden Betrieb durchzuführen. Selenium Wire hilft Ihnen, diese Einschränkungen zu überwinden, indem es die Interaktion mit Websites so ermöglicht, wie es reguläre menschliche Nutzer tun würden.

Hier sind einige Gründe, warum Sie Selenium Wire für Web-Scraping verwenden sollten:

  • Direkten Zugriff auf Netzwerkverkehr erhalten: Analysieren, überwachen und modifizieren Sie AJAX-Anfragen und -Antworten, um wertvolle Daten effizient zu extrahieren.
  • Anti-Bot-Erkennung umgehen: ChromeDriver gibt identifizierbare Details preis, die Anti-Bot-Systeme zur Erkennung nutzen. Technologien wie undetected-chromedriver nutzen Selenium Wire, um diese Details zu maskieren und Erkennungsmechanismen zu umgehen.
  • Browser-Flexibilität erhöhen: Traditionelle Browser basieren auf festen Startkonfigurationen, die einen Neustart erfordern, um Änderungen vorzunehmen. Selenium Wire ermöglicht Echtzeit-Updates von Anfrage-Headern und Proxy-Einstellungen innerhalb einer aktiven Sitzung und ist damit eine optimale Lösung für dynamisches Web-Scraping.

Key Features of Selenium Wire

Access Requests and Responses

Selenium Wire ermöglicht Ihnen, HTTP/HTTPS-Traffic aus dem Browser zu überwachen und zu erfassen, und bietet Zugriff auf die folgenden zentralen Attribute:

Attribute Description
driver.requests Es meldet die Liste der erfassten Anfragen in chronologischer Reihenfolge
driver.last_request Es meldet die zuletzt erfasste Anfrage
(Dies ist effizienter als die Verwendung von driver.requests[-1])
driver.wait_for_request(pat, timeout=10) Diese Methode wartet—die Zeit ist durch den Parameter timeout definiert—bis sie eine Anfrage sieht, die zu einem Muster passt, das durch den Parameter pat definiert ist—dies kann ein Substring oder ein regular expression sein.
driver.har Ein JSON-formatiertes HAR-Archiv der HTTP-Transaktionen, die stattgefunden haben.
driver.iter_requests() Es gibt einen Iterator über die erfassten Anfragen zurück.

Ein Selenium Wire Request Object hat die folgenden Attribute:

Attribute Description
body Der Request-Body wird als bytes dargestellt. Wenn die Anfrage keinen Body hat, ist der Wert von body leer (zum Beispiel: b'').
cert Es meldet Informationen über das SSL-Zertifikat des Servers im Dictionary-Format (es ist leer bei Nicht-HTTPS-Anfragen).
date Es zeigt das Datum/Uhrzeit an, zu der die Anfrage gestellt wurde.
headers Es meldet ein Dictionary-ähnliches Object der Anfrage-Header (beachten Sie, dass Header in Selenium Wire nicht case-sensitiv sind und Duplikate erlaubt sind).
host Es meldet den Anfrage-Host ( zum Beispiel https://brightdata.de/).
method Es spezifiziert die HHTP-Methode (GETPOST, etc…)
params Es meldet ein Dictionary der Anfrage-Parameter (beachten Sie, dass wenn ein Parameter mit demselben Namen mehr als einmal in der Anfrage vorkommt, sein Wert im Dictionary eine Liste sein wird).
path Es meldet den Anfragepfad.
querystring Es meldet den Query-String.
response Es meldet das Response-Object, das mit der Anfrage verknüpft ist (beachten Sie, dass der Wert None ist, wenn die Anfrage keine Antwort hat).
url Es meldet die Anfrage-URL vollständig mit hostpath und querystring.
ws_messages Falls eine Anfrage ein WebSocket ist (in diesem Fall ist die URL im Allgemeinen wie wss://), enthält ws_messages alle gesendeten und empfangenen WebSocket-Nachrichten.

Ein Response Object stellt stattdessen diese Attribute bereit:

Attribute Description
body Der Response-Body wird als bytes dargestellt. Wenn die Antwort keinen Body hat, ist der Wert von body leer (zum Beispiel: b'').
date Es zeigt das Datum/Uhrzeit an, zu der die Antwort empfangen wurde.
headers Es meldet ein Dictionary-ähnliches Object der Response-Header (beachten Sie, dass Header in Selenium Wire nicht case-sensitiv sind und Duplikate erlaubt sind).
reason Es meldet die Reason-Phrase der Antwort, wie OKNot Found, etc…
status_code Es meldet den Status der Antwort, wie 200404, etc…

Schreiben wir ein Python-Skript, um diese Funktion zu testen:

from seleniumwire import webdriver

# Initialize the WebDriver with Selenium Wire
driver = webdriver.Chrome()

try:
    # Open the target website
    driver.get("https://brightdata.de/")

    # Access and print all captured requests
    for request in driver.requests:
        print(f"URL: {request.url}")
        print(f"Method: {request.method}")
        print(f"Headers: {request.headers}")
        print(f"Response Status Code: {request.response.status_code if request.response else 'No Response'}")
        print("-" * 50)

finally:
    # Close the browser
    driver.quit()

Dieser Code öffnet die Ziel-Website und erfasst Anfragen mithilfe von driver.requests. Anschließend durchläuft er eine for-Schleife, um einige Anfrage-Attribute wie urlmethod und headers abzufangen.

Hier ist das erwartete Ergebnis:

Some of the logged requests

Intercept Requests and Responses

Selenium Wire ermöglicht das Abfangen und Modifizieren von Anfragen und Antworten mittels Interceptors—Funktionen, die ausgelöst werden, während Netzwerkverkehr durch den Browser fließt.

Es gibt zwei separate Interceptors:

  • driver.request_interceptor: fängt Anfragen ab und akzeptiert ein einzelnes Argument.
  • driver.response_interceptor: fängt die Antwort ab und akzeptiert zwei Argumente, eines für die auslösende Anfrage und eines für die Antwort.

Hier ist ein Beispiel, das zeigt, wie Sie einen Request-Interceptor verwenden:

from seleniumwire import webdriver

# Define the request interceptor function
def interceptor(request):
    # Add a custom header to all requests
    request.headers["X-Test-Header"] = "MyCustomHeaderValue"

    # Block requests to a specific domain
    if "example.com" in request.url:
        print(f"Blocking request to: {request.url}")
        request.abort()  # Abort the request

# Initialize the WebDriver with Selenium Wire
driver = webdriver.Chrome()

# Assign the interceptor function to the driver
driver.request_interceptor = interceptor

try:
    # Open a website that makes multiple requests
    driver.get("https://brightdata.de/")

    # Print all captured requests
    for request in driver.requests:
        print(f"URL: {request.url}")
        print(f"Headers: {request.headers}")
        print("-" * 50)

finally:
    # Close the browser
    driver.quit()

Das macht dieses Snippet:

  • Interceptor function: Erstellt eine Interceptor-Funktion, die für jede ausgehende Anfrage aufgerufen wird. Dies fügt allen ausgehenden Anfragen über request.headers[] einen benutzerdefinierten Header hinzu. Außerdem blockiert es Browser-Anfragen für die Domain example.com.
  • Captures requests: Nachdem die Seite geladen ist, werden alle erfassten Anfragen ausgegeben, einschließlich der modifizierten Header.

Hinweis:
  Das Blockieren von Anfragen ist vorteilhaft, wenn Seiten zusätzliche Ressourcen wie Ads, Analytics-Skripte oder Third-Party-Widgets laden, die für Ihre Aufgabe nicht essenziell sind. Dieser Ansatz verbessert die Scraping-Effizienz durch höhere Geschwindigkeit und minimiert den Bandbreitenverbrauch.

Das erwartete Ergebnis sollte in etwa so aussehen:

Note the X-Test-Header

WebSocket Monitoring

Viele moderne Websites verlassen sich auf WebSockets, um Echtzeitkommunikation mit Servern aufrechtzuerhalten. Im Gegensatz zu traditionellen HTTP-Anfragen erstellen WebSockets eine kontinuierliche Verbindung zwischen Browser und Server, wodurch ein nahtloser Datenaustausch ohne wiederholte Handshakes möglich wird.

Da entscheidende Daten häufig über diese Kanäle fließen, ermöglicht das Abfangen von WebSocket-Traffic den direkten Zugriff auf Echtzeit-Serverantworten, wodurch browserbasierte Verarbeitung oder Rendering überflüssig wird.

Hier sind die Attribute eines Selenium Wire WebSocket Objects:

Attribute Description
content Es meldet den Inhalt der Nachricht, der entweder ein str oder im bytes-Format sein kann.
date Es zeigt das Datum/Uhrzeit der Nachricht.
headers Es meldet ein Dictionary-ähnliches Object der Response-Header (beachten Sie, dass Header in Selenium Wire nicht case-sensitiv sind und Duplikate erlaubt sind).
from_client Dies ist ein Boolean, der True zurückgibt, wenn die Nachricht vom Client gesendet wurde, und False vom Server.

Manage Proxies

Proxy-Server fungieren als Vermittler zwischen Ihrem Gerät und Ziel-Websites, indem sie Ihre IP-Adresse verbergen. Sie erleichtern das Umgehen von IP-basierten Einschränkungen, reduzieren Blockierungen aufgrund von Ratenbegrenzung und ermöglichen den Zugriff auf geobeschränkte Inhalte für nahtloses Web-Scraping.

Konfigurieren wir einen Proxy in Selenium Wire:

# Set up Selenium Wire options
options = {
    "proxy": {
        "http": "<YOUR_HTTP_PROXY_URL>",
        "https": "<YOUR_HTTPS_PROXY_URL>"
    }
}

# Initialize the WebDriver with Selenium Wire
driver = webdriver.Chrome(seleniumwire_options=options)

Dieses Setup unterscheidet sich von der Proxy-Konfiguration in Vanilla Selenium, wo Sie auf das Chrome-Flag --proxy-server angewiesen sind. Das bedeutet, dass die Proxy-Konfiguration in Vanilla Selenium statisch ist. Nachdem ein Proxy gesetzt wurde, bleibt er für die gesamte Browser-Sitzung aktiv und kann nicht geändert werden, ohne den Browser neu zu starten. Diese Einschränkung kann limitierend sein, insbesondere wenn eine dynamische Proxy-Rotation erforderlich ist.

Im Gegensatz dazu bietet Selenium Wire die Flexibilität, Proxies dynamisch innerhalb derselben Browser-Instanz zu ändern. Das ist dank des proxy-Attributs möglich:

# Dynamically change the proxy
driver.proxy = {
    "http": "<NEW_HTTP_PROXY_URL>",
    "https": "<NEW_HTTPS_PROXY_URL>"
}

Außerdem unterstützt das Chrome-Flag --proxy-server keine Proxies mit Authentifizierungsdaten in der URL:

protocol://username:password@host:port

Stattdessen unterstützt Selenium Wire authentifizierte Proxies vollständig und ist damit die bessere Wahl für Web-Scraping.

Proxy Rotation in Selenium Wire

Richten wir ein Selenium Wire-Projekt für Proxy-Rotation ein. Damit ändert sich Ihre Exit-IP bei jeder Anfrage.

Requirements

Sie benötigen die folgenden Voraussetzungen, um diesem Teil des Leitfadens zu folgen:

Beginnen Sie mit dem Erstellen eines Virtual-Environment-Verzeichnisses:

python -m venv venv

Um es zu aktivieren, führen Sie unter Windows aus:

venv\Scripts\activate

Unter macOS/Linux führen Sie aus:

source venv/bin/activate

Installieren Sie nun Selenium Wire (Selenium wird automatisch als Dependency installiert):

pip install selenium-wire

Step 1: Randomize Proxies

Zuerst benötigen Sie eine Liste gültiger Proxy-URLs. Sie können unsere Liste free proxies verwenden. Fügen Sie sie einer Liste hinzu und verwenden Sie random.choice(), um ein zufälliges Element daraus auszuwählen:

def get_random_proxy():
    proxies = [
        "http://PROXY_1:PORT_NUMBER_X",
        "http://PROXY_2:PORT_NUMBER_Y",
        "http://PROXY_3:PORT_NUMBER_Z",
        # ...
    ]
    
    # Randomize the list
    return random.choice(proxies)

Nach dem Aufruf gibt diese Funktion eine zufällige Proxy-URL aus der Liste zurück.

Damit es funktioniert, vergessen Sie nicht, random zu importieren:

import random

Step 2: Set the Proxy

Rufen Sie die Funktion get_random_proxy() auf, um eine Proxy-URL zu erhalten:

proxy = get_random_proxy()

Initialisieren Sie die Browser-Instanz und setzen Sie den ausgewählten Proxy:

# Selenium Wire configuration with the proxy
seleniumwire_options = {
    "proxy": {
        "http": proxy,
        "https": proxy
    }
}

# Browser configuration
chrome_options = Options()
chrome_options.add_argument("--headless")  # Run the browser in headless mode 

# Initialize a browser instance with the given configurations
driver = webdriver.Chrome(service=Service(), options=chrome_options, seleniumwire_options=seleniumwire_options)

Das obige Snippet erfordert die folgenden Imports:

from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

Um den Proxy während der Browser-Sitzung dynamisch zu ändern, verwenden Sie stattdessen diesen Code:

driver.proxy = {
    "http": proxy,
    "https": proxy
}

Step 3: Visit the Target Page

Besuchen Sie die Ziel-Website, extrahieren Sie die Ausgabe und schließen Sie den Browser:

try:
    # Visit the target page
    driver.get("https://httpbin.io/ip")

    # Extract the page output
    body = driver.find_element(By.TAG_NAME, "body").text
    print(body)
except Exception as e:
    # Handle any errors that occur with the browser or the proxy
    print(f"Error with proxy {proxy}: {e}")
finally:
    # Close the browser
    driver.quit()

Damit es funktioniert, importieren Sie By aus Selenium:

from selenium.webdriver.common.by import By

In diesem Beispiel ist die Zielseite der /ip-Endpunkt aus dem HTTPBin-Projekt: Diese Seite gibt die IP-Adresse des Aufrufers zurück. Wenn alles wie erwartet funktioniert, sollte das Skript bei jedem Lauf eine andere IP aus der Proxy-Liste ausgeben.

Step 4: Put It All Together

Dies ist die vollständige Selenium Wire Proxy-Rotationslogik, die in Ihrer Datei selenium_wire.py stehen sollte:

import random
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

def get_random_proxy():
    proxies = [
        "http://PROXY_1:PORT_NUMBER_X",
        "http://PROXY_2:PORT_NUMBER_Y",
        "http://PROXY_3:PORT_NUMBER_Z",
        # Add more proxies here...
    ]
    
    # Randomly pick a proxy
    return random.choice(proxies)
 
# Pick a random proxy URL 
proxy = get_random_proxy()

# Selenium Wire configuration with the proxy
seleniumwire_options = {
    "proxy": {
        "http": proxy,
        "https": proxy
    }
}

# Browser configuration
chrome_options = Options()
chrome_options.add_argument("--headless")  # Run the browser in headless mode 

# Initialize a browser instance with the given configurations
driver = webdriver.Chrome(service=Service(), options=chrome_options, seleniumwire_options=seleniumwire_options)

try:
    # Visit the target page
    driver.get("https://httpbin.io/ip")

    # Extract the page output
    body = driver.find_element(By.TAG_NAME, "body").text
    print(body)
except Exception as e:
    # Handle any errors that occur with the browser or the proxy
    print(f"Error with proxy {proxy}: {e}")
finally:
    # Close the browser
    driver.quit()

Um die Datei auszuführen, starten Sie:

python3 selenium_wire.py

Bei jedem Lauf sollte die Ausgabe sein:

{
  "origin": "PROXY_1:XXXX"
}

Oder:

{
  "origin": "PROXY_2:YYYY"
}

Und so weiter…

Führen Sie das Skript mehrfach aus, und Sie werden jedes Mal eine andere IP-Adresse sehen.

A Better Approach to Proxy Rotation: Bright Data Proxies

Manuelle Proxy-Rotation in Selenium Wire erfordert viel Boilerplate-Code und die Pflege einer Liste gültiger Proxy-URLs. Stattdessen können Sie die Rotierenden Proxies von Bright Data verwenden, die IP-Adresswechsel automatisch handhaben. So können Sie sie nutzen.

Wenn Sie bereits ein Konto haben, melden Sie sich bei Bright Data an. Andernfalls erstellen Sie kostenlos ein Konto. Sie erhalten Zugriff auf das folgende User-Dashboard:

The Bright Data dashboard

Klicken Sie auf die Schaltfläche „View proxy products“:

View proxy products

Sie werden auf die Seite „Proxies & Scraping Infrastructure“ unten weitergeleitet:

Configuring your residential proxies

Scrollen Sie nach unten, suchen Sie die Karte „Residential Proxies“ und klicken Sie auf die Schaltfläche „Get started“:

Residential proxies

Sie gelangen zum Konfigurations-Dashboard für Residential Proxy. Folgen Sie dem geführten Wizard und richten Sie den Proxy-Service entsprechend Ihren Anforderungen ein.

Configuring your residential proxies

Gehen Sie zum Tab „Access parameters“ und rufen Sie Host, Port, Username und Password Ihres Proxy wie folgt ab:

access parameter

Beachten Sie, dass das Feld „Host“ den Port bereits enthält.

Das ist alles, was Sie benötigen, um die Proxy-URL zu erstellen und sie in Selenium Wire zu setzen. Sammeln Sie alle Informationen und erstellen Sie eine URL mit der folgenden Syntax:

<username>:<password>@<host>

Zum Beispiel wäre es in diesem Fall:

brd-customer-hl_4hgu8dwd-zone-residential:[email protected]:XXXXX

Aktivieren Sie „Active proxy“, folgen Sie den letzten Anweisungen, und Sie können loslegen!

Active proxy toggle

Hier ist das Selenium Wire Proxy-Snippet für die Bright Data-Integration:

# Bright Data proxy URL
proxy = "brd-customer-hl_4hgu8dwd-zone-residential:[email protected]:XXXXX"

# Set up Selenium Wire options
options = {
    "proxy": {
        "http": proxy,
        "https": proxy
    }
}

# Initialize the WebDriver with Selenium Wire
driver = webdriver.Chrome(seleniumwire_options=options)

Selenium vs Selenium Wire for Web Scraping

Zusammenfassend hier der Vergleich Selenium vs. Selenium Wire:

Selenium Selenium Wire
Purpose Automatisiert Webbrowser für UI-Tests und Web-Interaktionen Erweitert Selenium um zusätzliche Fähigkeiten zur Inspektion und Modifikation von HTTP/HTTPS-Anfragen und -Antworten
HTTP/HTTPS request handling Bietet keinen direkten Zugriff auf HTTP/HTTPS-Anfragen oder -Antworten Ermöglicht Inspektion, Modifikation und Erfassung von HTTP/HTTPS-Anfragen und -Antworten
Proxy support Hat eingeschränkte Proxy-Unterstützung (erfordert manuelle Konfiguration) Fortgeschrittenes Proxy-Management, mit Unterstützung für dynamisches Setzen
Performance Leichtgewichtig und schnell Etwas langsamer aufgrund der Erfassung und Verarbeitung des Netzwerkverkehrs
Use cases Primär für Funktionstests von Webanwendungen genutzt, praktisch für grundlegende Web-Scraping-Fälle Nützlich für das Testen von APIs, Debugging von Netzwerkverkehr und Web-Scraping

Conclusion

Während Selenium Wire für Web-Scraping effizient eingesetzt werden kann, handelt es sich um nicht mehr gepflegte Software und es ist keine One-Size-Fits-All-Lösung.

Erwägen Sie stattdessen die Verwendung von Vanilla Selenium mit einem dedizierten Scraping-Browser wie dem Scraping Browser from Bright Data. Es ist ein skalierbarer Cloud-Browser, der mit Playwright, Puppeteer, Selenium und anderen funktioniert. Er rotiert Exit-IPs nahtlos für jede Anfrage und verwaltet dabei Browser-Fingerabdruck, Wiederholungsversuche, CAPTCHA-Lösung und mehr. Testen Sie ihn, um Blocking-Probleme zu eliminieren und Ihren Scraping-Workflow zu optimieren.

About

Erfahren Sie, wie Sie Selenium Wire für Web-Scraping verwenden, Anfragen abfangen, Proxies rotieren und die Datenerfassung mit Python optimieren.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors