Dieser Leitfaden erklärt, wie Sie Selenium Wire für Web-Scraping verwenden, und behandelt Themen wie Anfrage-Interception und dynamische Proxy-Rotation.
- Was ist Selenium Wire?
- Warum Selenium Wire verwenden?
- Hauptfunktionen von Selenium Wire
- Proxy-Rotation in Selenium Wire
- Rotierende Proxies mit Bright Data Proxies
- Selenium vs. Selenium Wire für Web-Scraping
- Fazit
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.
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:
ChromeDrivergibt identifizierbare Details preis, die Anti-Bot-Systeme zur Erkennung nutzen. Technologien wieundetected-chromedrivernutzen 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.
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 (GET, POST, 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 host, path 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 OK, Not Found, etc… |
status_code |
Es meldet den Status der Antwort, wie 200, 404, 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 url, method und headers abzufangen.
Hier ist das erwartete Ergebnis:
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 Domainexample.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:
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. |
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.
Richten wir ein Selenium Wire-Projekt für Proxy-Rotation ein. Damit ändert sich Ihre Exit-IP bei jeder Anfrage.
Sie benötigen die folgenden Voraussetzungen, um diesem Teil des Leitfadens zu folgen:
- Python 3.7 oder höher
- Supported web browser
Beginnen Sie mit dem Erstellen eines Virtual-Environment-Verzeichnisses:
python -m venv venvUm es zu aktivieren, führen Sie unter Windows aus:
venv\Scripts\activateUnter macOS/Linux führen Sie aus:
source venv/bin/activateInstallieren Sie nun Selenium Wire (Selenium wird automatisch als Dependency installiert):
pip install selenium-wireZuerst 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
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 OptionsUm den Proxy während der Browser-Sitzung dynamisch zu ändern, verwenden Sie stattdessen diesen Code:
driver.proxy = {
"http": proxy,
"https": proxy
}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 ByIn 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.
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.pyBei 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.
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:
Klicken Sie auf die Schaltfläche „View proxy products“:
Sie werden auf die Seite „Proxies & Scraping Infrastructure“ unten weitergeleitet:
Scrollen Sie nach unten, suchen Sie die Karte „Residential Proxies“ und klicken Sie auf die Schaltfläche „Get started“:
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.
Gehen Sie zum Tab „Access parameters“ und rufen Sie Host, Port, Username und Password Ihres Proxy wie folgt ab:
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!
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)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 |
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.









