DrissionPage mit Proxys nutzen: Praxis-Tutorial für Web Scraping mit Chromium & HTTP

Ein praxisnaher Leitfaden zur Kombination von DrissionPage mit ProxyHat-Residential-Proxys: SessionPage, ChromiumPage, WebPage-Moduswechsel, Paket-Erfassung und Produktionsmuster für Python-Scraper.

DrissionPage Proxy Guide: One Python Tool for HTTP and Chromium Scraping
In diesem Artikel

DrissionPage und Proxys: Ein Werkzeug für HTTP und Browser

Wer in Python scrapet, kennt das Dilemma: requests ist schnell und günstig, scheitert aber an JavaScript-gerenderten Seiten; Playwright oder Selenium lösen das Rendering-Problem, kosten jedoch 5–10× mehr Ressourcen pro Request. DrissionPage schließt diese Lücke, indem es beide Welten in einer API vereint — und mit ProxyHat-Residential-Proxys skaliert das Ganze auf harte Ziele wie SERPs, E-Commerce-Plattformen und Social-Media-Daten.

Bevor wir in die Implementierung gehen, ein wichtiger Hinweis: Dieses Tutorial behandelt ausschließlich das Scraping öffentlich zugänglicher Daten. Die Nutzung muss den robots.txt-Regeln und den Nutzungsbedingungen der Zielseite entsprechen. In den USA kann unbefugter automatisierter Zugriff unter den Computer Fraud and Abuse Act (CFAA, 18 U.S.C. § 1030) fallen; in der EU greift die DSGVO (GDPR) bei personenbezogenen Daten. Wenn eine offizielle API existiert, sollte diese Vorrang haben.

Warum dieses Problem existiert: Die Kosten-Dichotomie

Ein Headless-Chromium-Prozess verbraucht typischerweise 150–400 MB RAM und benötigt 800–2000 ms für das Laden einer moderaten Seite. Ein HTTP-Request mit requests braucht dagegen 5–20 MB und 100–500 ms. Wenn Sie 10.000 Seiten scrapen, ist der Unterschied zwischen 15 GB und 2 GB RAM-Stunden — und zwischen 30 Minuten und 3 Stunden Laufzeit.

DrissionPage (offizielle Dokumentation) adressiert dies durch drei Seitenklassen:

  • SessionPage — HTTP-Modus, basierend auf requests.Session, mit Cookie-Persistenz und Keep-Alive.
  • ChromiumPage — Browser-Modus, gesteuert über das Chrome DevTools Protocol (CDP), ohne WebDriver-Schnittstelle, was es schneller und weniger erkennbar macht als Selenium.
  • WebPage — kombiniert beide Modi und teilt Cookies, Header und Session-State zwischen ihnen. Sie können mitten in einem Workflow von HTTP auf Browser umschalten.

Das bedeutet: Sie starten günstig im HTTP-Modus und eskalieren nur dann zum Browser, wenn JavaScript-Rendering oder XHR-Interception erforderlich sind. Das senkt die Infrastrukturkosten um 60–80 % in typischen Scraping-Pipelines.

DrissionPage Chromium vs. SessionPage: Wann was?

KriteriumSessionPage (HTTP)ChromiumPage (CDP)
RAM-Verbrauch5–20 MB150–400 MB
Latenz pro Request100–500 ms800–2000 ms
JavaScript-RenderingNeinJa
XHR/Fetch-InterceptionNeinJa (über listen)
Anti-Bot-ErkennungHöher (kein Browser-Fingerprint)Niedriger (echter Browser)
Proxy-Konfiguration
set_proxies()ChromiumOptions.set_proxy()
Kosten pro 10k Requests~$0,50 Compute~$5,00 Compute

Die idiomatic API: ele(), eles() und Locators

DrissionPage verwendet eine einheitliche Locator-Syntax, die in beiden Modi funktioniert. Das ist einer der größten Vorteile gegenüber der Kombination aus requests + BeautifulSoup + Selenium.

Locator-Syntax im Überblick

from DrissionPage import WebPage

page = WebPage()

# Tag-basierte Suche
input_elem = page.ele('tag:input')

# Attribut-basierte Suche
button = page.ele('@class=submit-btn')

# XPath
title = page.ele('xpath://h1[@id="product-title"]')

# Mehrere Elemente
links = page.eles('tag:a')

# Kombiniert: Tag + Attribut
login_form = page.ele('tag:form@class=login')

Die ele()-Methode gibt das erste passende Element zurück, eles() eine Liste. Beide Methoden funktionieren identisch im HTTP- und im Browser-Modus — ein Element, das Sie im HTTP-Modus gefunden haben, bleibt gültig, wenn Sie in den Browser-Modus wechseln (solange die Seite neu geladen wird).

ChromiumOptions konfigurieren

from DrissionPage import ChromiumOptions

co = ChromiumOptions()
co.headless(True)
co.set_argument('--no-sandbox')
co.set_argument('--disable-gpu')
co.set_argument('--window-size=1920,1080')
co.set_user_agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...')

# Proxy setzen — ProxyHat Residential
co.set_proxy('http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080')

page = ChromiumPage(co)

Hintergrund-XHR mit listen.start() erfassen

Eines der mächtigsten Features von ChromiumPage ist die Fähigkeit, Hintergrund-Requests abzufangen — JSON-APIs, die die Seite asynchron lädt. Das ist oft der Schlüssel, um versteckte APIs zu finden und Browser-Eskalation ganz zu vermeiden.

from DrissionPage import ChromiumPage, ChromiumOptions

co = ChromiumOptions()
co.set_proxy('http://user-country-DE-session-sess01:pass@gate.proxyhat.com:8080')
page = ChromiumPage(co)

# Auf XHR/Fetch-Requests lauschen, die JSON zurückgeben
page.listen.start('api/products')
page.get('https://example-shop.de/catalog')

# Warte auf das erste passende Paket
packet = page.listen.wait(count=1, timeout=10)
if packet:
    print(packet.response.body)  # JSON-Daten der Hintergrund-API
    print(packet.url)            # Die echte API-URL

Mit dieser Technik finden Sie oft die ungeschützte JSON-API hinter einer JavaScript-gerenderten Seite — und können dann im nächsten Lauf direkt über SessionPage (HTTP) auf diese API zugreifen, ohne den Browser starten zu müssen.

Proxys in DrissionPage konfigurieren

SessionPage: set_proxies()

from DrissionPage import SessionPage

page = SessionPage()
page.set_proxies({
    'http': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080',
    'https': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080',
})
page.get('https://httpbin.org/ip')
print(page.html)

ChromiumPage: ChromiumOptions.set_proxy()

from DrissionPage import ChromiumOptions, ChromiumPage

co = ChromiumOptions()
co.set_proxy('http://user-country-DE-city-berlin-session-sess42:pass@gate.proxyhat.com:8080')
page = ChromiumPage(co)
page.get('https://httpbin.org/ip')
print(page.ele('tag:pre').text)

Warum sind Residential-Proxys für harte Ziele notwendig? Datacenter-IPs werden von Cloud-Anbietern (AWS, Google Cloud, Azure) zugewiesen und sind auf Anti-Bot-Systemen oft blockiert oder mit CAPTCHAs belegt. Residential-IPs stammen von echten ISPs und haben eine viel niedrigere Erkennungsrate. ProxyHat bietet Standorte in über 90 Ländern mit City-Level-Geo-Targeting.

Komplettes Beispiel: WebPage mit Moduswechsel und ProxyHat

Das folgende Beispiel zeigt den idiomatischen DrissionPage-Workflow: Start im HTTP-Modus über einen US-Residential-Proxy, dann Eskalation zum Browser für eine JS-gerenderte Seite — mit durchgehendem Cookie- und Session-Sharing.

from DrissionPage import WebPage
import json

def build_proxyhat_user(country='US', session_id='abc123', city=None):
    """Erstellt einen ProxyHat-Benutzernamen mit Geo-Targeting und Sticky Session."""
    user = f'user-country-{country}'
    if city:
        user += f'-city-{city}'
    user += f'-session-{session_id}'
    return user

# ProxyHat-Konfiguration
PROXYHAT_HOST = 'gate.proxyhat.com'
PROXYHAT_PORT = 8080
PROXYHAT_PASS = 'your_password'

session_user = build_proxyhat_user(country='US', session_id='order-001')
proxy_url = f'http://{session_user}:{PROXYHAT_PASS}@{PROXYHAT_HOST}:{PROXYHAT_PORT}'

# WebPage initialisieren — startet im HTTP-Modus
page = WebPage()

# --- Phase 1: HTTP-Modus für die Übersichtsseite ---
page.set_proxies({'http': proxy_url, 'https': proxy_url})
page.get('https://example-shop.com/api/categories')

categories = json.loads(page.response.content)
print(f"Gefunden: {len(categories)} Kategorien")

# --- Phase 2: Browser-Eskalation für JS-gerenderte Produktdetails ---
# Cookies und Session-State werden automatisch übernommen
page.change_mode()  # Wechselt zu ChromiumPage

# Browser-Proxy muss separat gesetzt werden (vor Browser-Start)
from DrissionPage import ChromiumOptions
co = ChromiumOptions()
co.set_proxy(proxy_url)
co.headless(True)
page = WebPage(chromium_options=co)
page.get('https://example-shop.com/product/12345')

# Auf XHR lauschen, um die echte Produkt-API zu finden
page.listen.start('api/product')
page.get('https://example-shop.com/product/12345')
packet = page.listen.wait(count=1, timeout=15)

if packet:
    product_data = json.loads(packet.response.body)
    print(f"Produkt: {product_data['name']}, Preis: {product_data['price']}")
else:
    # Fallback: DOM-Scraping
    name = page.ele('@class=product-title').text
    price = page.ele('@class=price').text
    print(f"Produkt (DOM): {name}, Preis: {price}")

Dieses Pattern — HTTP zuerst, Browser nur bei Bedarf — reduziert die Browser-Starts um typischerweise 70–90 %, wenn die meisten Seiten eine zugängliche API im Hintergrund haben.

Produktionsmuster: Skalierung, Retries und Concurrency

1. Per-Session Proxy-Pinning

Für Login-Flows und mehrstufige Workflows müssen alle Requests von derselben IP kommen. ProxyHat unterstützt Sticky Sessions über den -session-{id}-Flag im Benutzernamen. Die Session bleibt für bis zu 30 Minuten an dieselbe IP gebunden.

import uuid

def make_page_for_session(country='US'):
    sid = uuid.uuid4().hex[:12]
    user = f'user-country-{country}-session-{sid}'
    proxy = f'http://{user}:pass@gate.proxyhat.com:8080'
    
    page = WebPage()
    page.set_proxies({'http': proxy, 'https': proxy})
    return page, sid

2. Retries mit exponentiellem Backoff

import time

def fetch_with_retry(page, url, max_retries=3):
    for attempt in range(max_retries):
        try:
            resp = page.get(url, timeout=15)
            if resp.status_code == 200:
                return resp
            elif resp.status_code == 429:
                wait = 2 ** attempt * 5  # 5s, 10s, 20s
                print(f"Rate-limited, warte {wait}s")
                time.sleep(wait)
            else:
                print(f"Status {resp.status_code}, Retry {attempt+1}")
                time.sleep(2 ** attempt)
        except Exception as e:
            print(f"Fehler: {e}, Retry {attempt+1}")
            time.sleep(2 ** attempt)
    return None

3. Concurrency-Limits und Parallelität

DrissionPage ist nicht async-nativ. Für Parallelität verwenden Sie concurrent.futures.ThreadPoolExecutor für SessionPage oder mehrere ChromiumPage-Instanzen in separaten Prozessen. Eine Faustregel: maximal 5–10 gleichzeitige Browser-Instanzen pro CPU-Kern, 50–100 gleichzeitige HTTP-Sessions pro Kern.

from concurrent.futures import ThreadPoolExecutor, as_completed

def scrape_url(url):
    page = SessionPage()
    sid = url.split('/')[-1]  # Eindeutige Session pro URL
    proxy = f'http://user-country-US-session-{sid}:pass@gate.proxyhat.com:8080'
    page.set_proxies({'http': proxy, 'https': proxy})
    page.get(url)
    return page.ele('tag:title').text

urls = ['https://example.com/page/1', 'https://example.com/page/2']

with ThreadPoolExecutor(max_workers=20) as executor:
    futures = {executor.submit(scrape_url, u): u for u in urls}
    for f in as_completed(futures):
        try:
            result = f.result(timeout=30)
            print(result)
        except Exception as e:
            print(f"Fehler: {e}")

4. Versteckte APIs über listen finden

Der listen-Mechanismus ist Ihr wichtigstes Werkzeug, um Browser-Eskalation zu vermeiden. Starten Sie den Browser einmalig, erfassen Sie alle XHR/Fetch-Requests, identifizieren Sie die JSON-Endpunkte — und scrapen Sie danach ausschließlich über SessionPage. Ein typischer E-Commerce-Shop lädt 3–8 Hintergrund-APIs pro Seitenaufruf; oft sind Preis-, Bewertung- und Verfügbarkeitsdaten über direkte JSON-Endpunkte zugänglich.

Wann Sie NICHT zum Browser eskalieren sollten

  • Statische HTML-Seiten — wenn der Inhalt im Quelltext steht, ist SessionPage ausreichend und 10× schneller.
  • Bekannte JSON-APIs — wenn Sie die API-URL kennen (z. B. über listen gefunden), rufen Sie sie direkt auf.
  • Massen-Downloads — für Tausende von Produktseiten mit bekannter Struktur ist der Browser-Overhead nicht vertretbar.
  • Sitemaps und RSS-Feeds — diese sind per Definition maschinenlesbar und benötigen kein Rendering.

Eskalieren Sie zum Browser nur, wenn: (a) die Seite JavaScript benötigt, um den Inhalt zu rendern, (b) Sie mit interaktiven Elementen arbeiten müssen (Klicks, Scrollen, Formulare), oder (c) Sie XHR-Requests abfangen müssen, um eine versteckte API zu finden.

ProxyHat-spezifische Einrichtung

ProxyHat bietet drei Proxy-Typen, die alle über denselben Gateway gate.proxyhat.com erreichbar sind:

TypUse CaseEmpfehlung für DrissionPage
ResidentialSERPs, E-Commerce, Social MediaStandardwahl für harte Ziele
MobileApp-APIs, mobil-spezifische InhalteWenn die Seite Mobile-IPs erfordert
DatacenterSchnelle, ungeschützte APIsKostenoptimiert für Phase 1 (HTTP)

Die ProxyHat-Preise sind nutzungsbasiert. Für DrissionPage-Workflows empfiehlt sich eine Kombination: Datacenter-Proxys für die HTTP-Phase (niedrige Kosten, hohe Geschwindigkeit) und Residential-Proxys für die Browser-Phase (höhere Erfolgsquote bei Anti-Bot-Checks).

Weitere Details zur Konfiguration finden Sie in der ProxyHat-Dokumentation. Für spezifische Use Cases siehe Web Scraping und SERP Tracking.

Häufige Fehler und Edge Cases

  • Proxy wird im Browser-Modus nicht angewendetset_proxy() muss auf ChromiumOptions vor der Browser-Erstellung gesetzt werden, nicht nachträglich auf der Page.
  • Session-Verlust beim ModuswechselWebPage.change_mode() überträgt Cookies automatisch, aber benutzerdefinierte Header müssen manuell neu gesetzt werden.
  • listen.wait() blockiert endlos — setzen Sie immer einen timeout-Wert. Wenn die Seite asynchron lädt, warten Sie zusätzlich auf ein DOM-Element, bevor Sie listen.wait() aufrufen.
  • Zu viele Browser-Instanzen — jeder ChromiumPage-Prozess hält einen echten Browser offen. Schließen Sie Pages mit page.close(), um Zombie-Prozesse zu vermeiden.
  • Proxy-Rotation ignoriert Sessions — wenn Sie Sticky Sessions verwenden, dürfen Sie nicht auch -rotate-1 setzen. Wählen Sie einen Modus pro Request.

Key Takeaways

  • DrissionPage vereint HTTP- und Browser-Scraping in einer API — nutzen Sie SessionPage für 80–90 % der Requests und eskalieren Sie nur bei Bedarf zu ChromiumPage.
  • Residential-Proxys sind für harte Ziele unerlässlich; Datacenter-IPs reichen für ungeschützte APIs.
  • listen.start() ist Ihr wichtigstes Werkzeug, um versteckte JSON-APIs zu finden und Browser-Overhead zu eliminieren.
  • ProxyHat-Sticky-Sessions (-session-{id}) garantieren IP-Konsistenz für mehrstufige Workflows.
  • Concurrency: 50–100 HTTP-Sessions pro Kern, 5–10 Browser-Instanzen pro Kern — nicht mehr.
  • Ethik: Nur öffentliche Daten, robots.txt respektieren, offizielle APIs bevorzugen, DSGVO/CFAA beachten.

DrissionPage mit ProxyHat-Residential-Proxys gibt Ihnen die Werkzeuge, um praktisch jede öffentliche Webseite effizient und zuverlässig zu scrapen — mit der Geschwindigkeit von HTTP und der Macht eines echten Browsers, genau dann, wenn Sie ihn brauchen.

Häufig gestellte Fragen

Was ist DrissionPage?

DrissionPage ist ein Python-Framework für Web Scraping, das HTTP-Requests (SessionPage) und Chromium-Browser-Steuerung (ChromiumPage) in einer einzigen API vereint. Die WebPage-Klasse kann zwischen beiden Modi wechseln, während Cookies und Session-State erhalten bleiben. Das reduziert die Kosten, da nicht für jeden Request ein Browser gestartet werden muss.

Warum ist DrissionPage wichtig für Proxy-Nutzer?

DrissionPage erlaubt die nahtlose Integration von Proxys in beiden Modi — HTTP und Browser. Proxy-Nutzer profitieren davon, dass sie Residential-Proxys nur dann einsetzen müssen, wenn der Browser-Modus erforderlich ist, und für einfache HTTP-Requests günstigere Datacenter-Proxys verwenden können. Zudem unterstützt die listen-API das Abfangen von XHR-Requests, was oft Browser-Eskalation überflüssig macht.

Welcher Proxy-Typ funktioniert am besten mit DrissionPage?

Für harte Ziele wie SERPs, E-Commerce-Plattformen und Social-Media-Sites sind Residential-Proxys die beste Wahl, da sie von echten ISPs stammen und eine niedrigere Erkennungsrate haben. Datacenter-Proxys eignen sich für ungeschützte APIs und die HTTP-Phase. Mobile-Proxys sind spezifisch für App-APIs und mobil-optimierte Inhalte. Eine Kombination aus Datacenter und Residential ist oft die kosteneffizienteste Lösung.

Wie vermeidet man Blocks bei der Implementierung mit DrissionPage?

Verwenden Sie Residential-Proxys mit Sticky Sessions für mehrstufige Workflows, setzen Sie realistische User-Agent-Header, implementieren Sie exponentielles Backoff bei Rate-Limits (Status 429), und begrenzen Sie die Concurrency auf 50–100 HTTP-Sessions bzw. 5–10 Browser-Instanzen pro CPU-Kern. Nutzen Sie die listen-API, um versteckte JSON-Endpunkte zu finden und Browser-Overhead zu minimieren. Respektieren Sie robots.txt und verwenden Sie offizielle APIs, wenn verfügbar.

Bereit loszulegen?

Residential-, ISP- und Mobile-Proxys in über 148 Ländern. Erstelle ein kostenloses Konto.

Kostenloses Konto erstellen
← Zurück zum Blog