DrissionPage ist ein Python-Framework, das zwei Welten zusammenführt, die Scraper sonst mühsam verbinden müssen: die Geschwindigkeit von requests-ähnlichen HTTP-Clients und die Macht eines echten Chromium-Browsers über das Chrome DevTools Protocol (CDP). Wer ernsthaft DrissionPage Web Scraping betreibt, kennt das Dilemma: Für einfache API-Endpunkte reicht ein HTTP-Client, doch sobald JavaScript-Rendering oder Login-Flows ins Spiel kommen, braucht man einen Browser. DrissionPage löst das mit einem einheitlichen Objektmodell – SessionPage, ChromiumPage und WebPage –, das den Moduswechsel ohne State-Verlust erlaubt. In diesem DrissionPage Tutorial zeigen wir, wie Sie das Framework mit einem DrissionPage Proxy von ProxyHat kombinieren, um harte Anti-Bot-Ziele zuverlässig zu scrapen.
Rechtlicher Hinweis: Scraping öffentlicher Daten kann zulässig sein, unterliegt aber je nach Gerichtsbarkeit Einschränkungen durch das Computer Fraud and Abuse Act (CFAA) in den USA oder die DSGVO in der EU. Respektieren Sie robots.txt, Nutzungsbedingungen und Ratenlimits. Bevorzugen Sie offizielle APIs, wo immer verfügbar.
DrissionPage-Modell verstehen: SessionPage, ChromiumPage und WebPage
DrissionPage (offizielle Dokumentation) baut auf drei Kernklassen auf, die denselben Locator- und Interaktions-API teilen, aber unterschiedlich transportieren:
- SessionPage – nutzt
requests.Sessionunter der Haube. Ideal für statische HTML-Seiten, JSON-APIs und Endpunkte, die kein JavaScript benötigen. Sehr schnell, geringer Ressourcenverbrauch. - ChromiumPage – steuert einen echten Chromium-Browser über CDP. Wird für JS-gerenderte Single-Page-Apps, Login-Flows und CAPTCHA-Interaktionen benötigt. DrissionPage Chromium ist kein headless-Hack, sondern eine direkte DevTools-Verbindung, die stabiler ist als Selenium-WebDriver.
- WebPage – kombiniert beide Modi in einem Objekt. Sie starten im HTTP-Modus, können dann mit
page.change_mode()auf den Browsermodus wechseln, wobei Cookies und Session-State erhalten bleiben.
Warum das wichtig ist: Ein typischer Scraper muss für eine einzelne Site oft beides tun – eine JSON-API abrufen und danach eine gerenderte Seite interpretieren. Ohne DrissionPage schreiben Sie zwei Codepfade, synchronisieren Cookies manuell und verlieren State. Mit DrissionPage bleibt das WebPage-Objekt die einzige Quelle der Wahrheit.
Kostenaspekt: Ein Browser-Prozess verbraucht typischerweise 200–500 MB RAM und startet in 1–3 Sekunden. Ein HTTP-Request über SessionPage braucht unter 50 ms und fast keinen Speicher. Wenn Sie 90 % Ihrer Ziele über HTTP abwickeln können, sinkt Ihre Infrastrukturkosten dramatisch. DrissionPage zwingt Sie nicht, immer den Browser zu starten – Sie eskalieren nur, wenn es nötig ist.
Architektur auf einen Blick
| Modus | Transport | Typische Latenz | JS-Support | Speicher |
|---|---|---|---|---|
| SessionPage | HTTP via requests | 50–200 ms | Nein | ~20 MB |
| ChromiumPage | CDP | 800–3000 ms | Ja | 200–500 MB |
| WebPage | Beide, umschaltbar | Modusabhängig | Ja | Modusabhängig |
Die idiomatische API: ele(), eles() und Listen-Capture
DrissionPage verwendet eine eigene Locator-Syntax, die prägnanter ist als reine XPath-Ausdrücke, aber beide unterstützt. Die wichtigsten Methoden sind ele() (ein Element) und ele('xpath://...').
Locator-Syntax Beispiele
from DrissionPage import WebPage
page = WebPage()
page.get('https://example.com')
# Tag + Attribut
btn = page.ele('tag:button@class=submit')
# XPath
link = page.ele('xpath://a[contains(@href, "/product/")]')
# CSS-Selektor
box = page.ele('css:.price-tag')
# Alle Treffer
items = page.eles('tag:div@class=item-card')
for item in items:
print(item.text)
Die @-Syntax kombiniert Tag und Attribut in einem kompakten String. Das ist besonders nützlich, wenn Sie viele ähnliche Elemente scrapen und nicht jedes Mal XPath schreiben wollen.
ChromiumOptions konfigurieren
from DrissionPage import ChromiumOptions
co = ChromiumOptions()
co.headless(True)
co.set_argument('--no-sandbox')
co.set_argument('--disable-gpu')
co.set_user_agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')
co.auto_port() # zufälliger Debug-Port, vermeidet Konflikte
Hintergrund-XHR mit listen.start() abfangen
Eines der mächtigsten Features von DrissionPage ist die Fähigkeit, Netzwerkpakete im Hintergrund mitzuschneiden, während der Browser normal arbeitet. Das ist Gold wert, wenn eine Seite JSON-Daten über XHR lädt, die nicht im HTML stehen.
page = ChromiumPage()
page.listen.start('api/products') # Filter auf URL-Substring
page.get('https://shop.example.com/catalog')
packet = page.listen.wait(timeout=10)
if packet:
json_data = packet.response.body
print(json_data)
Damit finden Sie versteckte APIs, ohne manuell DevTools zu durchsuchen. In der Produktion können Sie so oft den Browsermodus komplett vermeiden, wenn Sie die XHR-Endpunkte einmal identifiziert haben.
Proxys in DrissionPage konfigurieren
Ein DrissionPage Proxy wird je nach Modus unterschiedlich gesetzt. SessionPage nutzt die set_proxies()-Methode, ChromiumPage geht über ChromiumOptions.set_proxy(). Beide unterstützen HTTP- und SOCKS5-Proxys.
SessionPage mit Proxy
from DrissionPage import SessionPage
page = SessionPage()
page.set_proxies('http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080')
page.get('https://httpbin.org/ip')
print(page.html)
ChromiumPage mit Proxy
from DrissionPage import ChromiumPage, ChromiumOptions
co = ChromiumOptions()
co.set_proxy('http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080')
co.headless(True)
page = ChromiumPage(co)
page.get('https://httpbin.org/ip')
print(page.ele('tag:pre').text)
Warum Residential Proxys? Datacenter-IPs werden von vielen Anti-Bot-Systemen (Cloudflare, Datadome, PerimeterX) sofort blockiert, da ihre IP-Bereiche bekannt sind. Residential Proxys verwenden IPs echter ISPs und sind wesentlich schwerer zu erkennen. Für harte Ziele wie E-Commerce-Preisvergleiche oder SERP-Scraping sind Residential Proxys praktisch Pflicht. ProxyHat bietet Residential-, Mobile- und Datacenter-Proxys – Details finden Sie auf der Preisseite und der Standortübersicht.
Runnable Beispiel: WebPage mit Moduswechsel und ProxyHat
Das folgende Beispiel zeigt einen vollständigen Workflow: Wir starten im HTTP-Modus über einen US-Residential-Proxy, scrapen eine JSON-API, und eskalieren dann auf den Browsermodus für eine JS-gerenderte Seite – alles in einem WebPage-Objekt mit geteiltem Cookie-State.
from DrissionPage import WebPage
import json
def build_username(country='US', session='abc123'):
return f'user-country-{country}-session-{session}'
username = build_username(country='US', session='order-42')
password = 'your_password'
proxy_url = f'http://{username}:{password}@gate.proxyhat.com:8080'
page = WebPage()
# --- Modus 1: HTTP / SessionPage ---
page.set_proxies(proxy_url)
page.get('https://api.example.com/v1/products?limit=50')
data = json.loads(page.html)
print(f"{len(data['items'])} Produkte via HTTP geladen")
# --- Modus 2: Browser / ChromiumPage ---
# Cookies und Session-State bleiben erhalten
page.change_mode() # wechselt zu ChromiumPage
# Proxy für den Browser neu setzen, da CDP separaten Proxy benötigt
from DrissionPage import ChromiumOptions
co = ChromiumOptions()
co.set_proxy(proxy_url)
co.headless(True)
page._control_options = co # interne Zuweisung für Demo; in Produktion sauber trennen
page.get('https://app.example.com/dashboard')
page.listen.start('api/user')
page.get('https://app.example.com/dashboard')
packet = page.listen.wait(timeout=15)
if packet:
user_json = packet.response.body
print(json.dumps(user_json, indent=2)[:500])
page.quit()
Hinweis: In einer echten Produktionsumgebung sollten Sie den Moduswechsel sauber kapseln und den Proxy für den Browsermodus explizit über ChromiumOptions setzen, bevor Sie change_mode() aufrufen. Die obige Demo zeigt das Prinzip; für Details siehe die ProxyHat-Dokumentation.
Produktionsmuster: Proxy-Pinning, Retries und Paketanalyse
Per-Session Proxy-Pinning
Anti-Bot-Systeme erkennen IP-Sprünge innerhalb einer Session als verdächtig. Verwenden Sie eine feste Session-ID pro logischer Sitzung, damit der Residential-Proxy dieselbe IP behält:
import uuid
def make_session_proxy(country='US'):
session_id = uuid.uuid4().hex[:12]
user = f'user-country-{country}-session-{session_id}'
return f'http://{user}:pass@gate.proxyhat.com:8080'
# Pro Scraper-Task eine eigene Session
proxy = make_session_proxy('DE')
page = SessionPage()
page.set_proxies(proxy)
Bei ProxyHat bleibt eine Session typischerweise 10–30 Minuten stabil, je nach Pool-Verfügbarkeit. Für Langzeitsessions verwenden Sie Sticky-Session-Flags im Benutzernamen.
Retries mit exponentiellem Backoff
import time
from DrissionPage import SessionPage
def fetch_with_retry(url, max_retries=4, base_delay=1.0):
for attempt in range(max_retries):
try:
page = SessionPage()
page.set_proxies(make_session_proxy('US'))
page.get(url, timeout=15)
if page.status == 200:
return page
except Exception as e:
print(f"Versuch {attempt+1} fehlgeschlagen: {e}")
time.sleep(base_delay * (2 ** attempt))
return None
Versteckte APIs über listen finden
Viele moderne Sites laden Daten über XHR-Endpunkte, die nicht im Quellcode sichtbar sind. Mit listen.start() können Sie den Datenstrom abfangen und anschließend direkt über SessionPage aufrufen – ohne Browser:
# Schritt 1: Browser nutzen, um XHR-Endpunkt zu finden
page = ChromiumPage(ChromiumOptions().headless(True))
page.listen.start('api/')
page.get('https://target.example.com')
packets = []
for _ in range(20):
p = page.listen.wait(timeout=5)
if p:
packets.append(p.url)
page.quit()
# Schritt 2: Endpunkt direkt via HTTP aufrufen
http_page = SessionPage()
http_page.set_proxies(make_session_proxy('US'))
http_page.get(packets[0])
print(http_page.json)
Dieses Muster reduziert die Browser-Starts um 80–95 %, sobald die API-Struktur bekannt ist.
Parallelität und Concurrency-Limits
Browser-Instanzen sind teuer. Faustregel: Nicht mehr als 2–4 gleichzeitige ChromiumPage-Instanzen pro CPU-Kern. SessionPage kann problemlos 50–100 parallele Requests pro Worker verarbeiten. Für größere Fleets verwenden Sie Containerisierung mit Docker und einen Worker-Pool:
from concurrent.futures import ThreadPoolExecutor
def scrape_one(url):
page = SessionPage()
page.set_proxies(make_session_proxy('US'))
page.get(url, timeout=15)
result = page.ele('tag:h1').text
page.close()
return result
urls = ['https://example.com/p/1', 'https://example.com/p/2', 'https://example.com/p/3']
with ThreadPoolExecutor(max_workers=20) as pool:
results = list(pool.map(scrape_one, urls))
Begrenzen Sie die Parallelität auf das, was Ihr Proxy-Plan zulässt. ProxyHat erlaubt hohe Concurrency, aber jeder Plan hat faire Nutzungslimits – konsultieren Sie die Preisseite für Details.
Wann Sie NICHT auf den Browser eskalieren sollten
Nicht jede Seite braucht Chromium. Wenn eine der folgenden Bedingungen zutrifft, bleiben Sie bei SessionPage:
- Die Seite liefert vollständiges HTML im Quellcode (kein client-side Rendering).
- Es existiert eine JSON-API, die Sie direkt aufrufen können.
- Die Ziel-URL ist eine statische Ressource (PDF, CSV, XML).
- Latenz ist kritisch (z. B. Echtzeit-Preismonitoring mit < 500 ms Anforderung).
Der Browser sollte die Ausnahme sein, nicht die Regel. Ein häufiger Anfängerfehler ist, ChromiumPage für alles zu verwenden – das verzehnfacht Ihre Infrastrukturkosten ohne Mehrwert.
Ethik und rechtliche Rahmenbedingungen
Scraping ist ein Werkzeug, kein Freifahrtschein. Beachten Sie folgende Grundsätze:
- Öffentliche Daten nur: Scrapen Sie keine Daten hinter Login-Walls ohne Erlaubnis. Das CFAA in den USA und ähnliche Gesetze in anderen Ländern können unbefugten Zugriff kriminalisieren.
- DSGVO beachten: Wenn Sie personenbezogene Daten aus der EU scrapen, greift die DSGVO. Die DSGVO-Übersicht der EU bietet einen guten Einstieg.
- robots.txt respektieren: Auch wenn sie nicht rechtlich bindend ist, signalisiert sie den Willen des Site-Betreibers.
- Ratenlimits einhalten: Überschwemmen Sie keine Server. 1–2 Requests pro Sekunde pro Domain ist ein vernünftiges Maximum.
- Offizielle APIs bevorzugen: Wenn eine Site eine API anbietet, nutzen Sie diese. Sie ist stabiler, schneller und rechtlich sicherer.
Weitere Anwendungsfälle für Proxy-basiertes Scraping finden Sie auf unseren Seiten zu Web Scraping und SERP-Tracking.
Key Takeaways
- DrissionPage vereint HTTP- und Browser-Scraping in einem Objektmodell – SessionPage für Geschwindigkeit, ChromiumPage für JS-Rendering, WebPage für nahtlosen Moduswechsel.
- Die Locator-Syntax mit
ele()und@-Attributfiltern ist kompakter als reines XPath und deckt 95 % der Fälle ab. listen.start()ist der Schlüssel zu versteckten APIs: Fangen Sie XHR-Pakete ab und rufen Sie die Endpunkte danach direkt über SessionPage auf.- Proxy-Konfiguration erfolgt über
set_proxies()(SessionPage) bzw.ChromiumOptions.set_proxy()(Browser). Residential Proxys sind für harte Ziele unerlässlich. - ProxyHat-Verbindung:
gate.proxyhat.com:8080(HTTP) oder:1080(SOCKS5), mit Geo- und Session-Flags im Benutzernamen. - Eskalieren Sie nur auf den Browser, wenn HTTP nicht ausreicht. Das spart 80–95 % der Infrastrukturkosten.
FAQ
Was ist DrissionPage?
DrissionPage ist ein Python-Web-Automatisierungsframework, das HTTP-Anfragen (ähnlich requests) und Chromium-Browsersteuerung über CDP in einer einheitlichen API kombiniert. Es erlaubt den Wechsel zwischen HTTP- und Browsermodus innerhalb eines Objekts, ohne dass Cookies oder Session-State verloren gehen.
Warum ist DrissionPage für Proxy-Nutzer relevant?
Weil es beide Transportmodi mit demselben Proxy-Objekt unterstützt. Sie können einen Residential-Proxy für schnelle HTTP-Calls und für browserbasierte JS-Rendering-Aufgaben verwenden, ohne zwei separate Tools oder Cookie-Synchronisation zwischen requests und Selenium pflegen zu müssen.
Welcher Proxy-Typ funktioniert am besten mit DrissionPage?
Residential Proxys sind die beste Wahl für harte Anti-Bot-Ziele, da sie echte ISP-IPs verwenden und seltener blockiert werden. Datacenter-Proxys reichen für einfache, ungeschützte Sites. Mobile Proxys bieten die höchste Vertrauensstufe, sind aber teurer. ProxyHat bietet alle drei Typen.
Wie vermeidet man Blöcke beim DrissionPage-Einsatz?
Verwenden Sie Residential Proxys mit Sticky Sessions, rotieren Sie Session-IDs pro logischer Sitzung, setzen Sie realistische User-Agent-Header, begrenzen Sie die Parallelität auf 1–2 Requests pro Sekunde pro Domain, und eskalieren Sie nur auf den Browsermodus, wenn HTTP nicht ausreicht. listen.start() hilft, versteckte APIs zu finden und Browser-Starts zu minimieren.
Kann DrissionPage mit SOCKS5-Proxys umgehen?
Ja. Sowohl SessionPage als auch ChromiumOptions unterstützen SOCKS5. Bei ProxyHat verwenden Sie Port 1080 für SOCKS5 und Port 8080 für HTTP. Das Format lautet socks5://user-country-DE:pass@gate.proxyhat.com:1080.






