Scrapen ohne blockiert zu werden: ein praxisnaher Leitfaden mit Code
Wirst du beim Scraping blockiert, bedeutet das meist eines von drei Dingen: Du hast zu viele Anfragen zu schnell gesendet, dein Client sah nicht wie ein Browser oder ein bekannter Bot aus, oder deine IP-Adresse steht auf einer Liste, der die Seite weniger vertraut. Du kannst alle drei mit ein paar Gewohnheiten verringern: die Blockade früh bemerken, langsamer werden, wenn die Seite zurückdrückt, eine konsistente und ehrliche Identität führen und Proxys nur dort einsetzen, wo sie passen. Dieser Leitfaden geht jeden Punkt mit funktionierendem Code durch. Verwende ihn für Seiten, die du scrapen darfst.
Eine Blockade erkennen
Eine Blockade sieht nicht immer wie eine Fehlerseite aus. Achte auf:
- 403 Forbidden, was oft bedeutet, dass die Seite deinen Client abgelehnt hat. Halte an und prüfe, ob du dort überhaupt sein darfst, bevor du es erneut versuchst.
- 429 Too Many Requests, was bedeutet, dass du zu viel sendest. Oft kommt ein Header
Retry-Aftermit. - 503 Service Unavailable, was überlastete Server bedeuten kann. Geh zurück.
- Eine 200-Antwort mit fast keinem Inhalt, eine Weiterleitung auf eine Login- oder Prüfseite oder eine Seite, der die erwarteten Daten fehlen.
Protokolliere für jeden Fehler den Statuscode und einen kurzen Ausschnitt des Inhalts. Eine Blockade, die du nicht in deinen Logs siehst, kannst du nicht beheben.
Mit Wiederholungen zurückschalten
Wenn die Seite sagt "langsamer", sollte dein Code deutlich mehr als ein bisschen langsamer werden. Exponentielles Zurückschalten mit einer Obergrenze für Versuche ist der Standardansatz. Er respektiert außerdem Retry-After, wenn die Seite den Header sendet:
import time
import requests
session = requests.Session()
session.headers.update({
"User-Agent": "ExampleBot/1.0 (+https://example.com/bot)",
"Accept-Language": "en-US,en;q=0.9",
})
def polite_get(url: str, max_attempts: int = 4) -> requests.Response:
delay = 2.0
resp = None
for _ in range(max_attempts):
resp = session.get(url, timeout=30)
if resp.status_code not in (429, 503):
return resp
retry_after = resp.headers.get("Retry-After", "")
wait = float(retry_after) if retry_after.isdigit() else delay
time.sleep(wait)
delay *= 2
return resp # immer noch blockiert: die letzte Antwort an den Aufrufer zurückgeben
resp = polite_get("https://example.com/products?page=1")
print(resp.status_code, len(resp.text))
Beachte, was die Funktion nicht tut. Sie wiederholt ein 403 nicht, und sie wechselt nicht durch Identitäten, um an einer Sperre vorbeizukommen. Ein 403 ist eine Entscheidung zum Anhalten, kein Rätsel, das man lösen muss.
Eine Blockade Schritt für Schritt diagnostizieren
Wenn ein Lauf anfängt zu scheitern, arbeite diese Prüfungen ab, bevor du sonst etwas änderst:
- Schau dir die erste fehlschlagende URL und ihren Statuscode an. Eine Blockade beginnt meist an einem bestimmten Punkt, nicht zufällig.
- Vergleiche die Anfragerate in den Minuten vor dem ersten Fehler. Ein Schwall ist die häufigste Ursache.
- Prüfe, ob der Fehler an einen Pfad, einen Bereich oder eine Tageszeit gebunden ist.
- Rufe dieselbe URL einmal von Hand in einem normalen Browser auf. Lädt der Browser sie, liegt der Unterschied im Muster deiner Anfragen. Ist auch der Browser gesperrt, hat die Seite vorerst aufgehört, dir Inhalte auszuliefern.
- Erst dann den Code ändern. Zuerst langsamer werden, dann Zurückschalten hinzufügen, und deine Identität zuletzt prüfen.
Wenn du mehrere Dinge gleichzeitig änderst, ist unmöglich zu wissen, was geholfen hat.
Eine konsistente, ehrliche Identität führen
Scraper werden blockiert, wenn sich ihre Identität zwischen Anfragen ändert oder nicht zum Rest des Datenverkehrs passt. Eine einzelne Sitzung mit einem klaren User-Agent ist die einfachste stabile Identität. Gib deinem Bot einen Namen, füge einen Kontaktlink hinzu und sende nur die Header, die ein gewöhnlicher Client senden würde. Den User-Agent zu wechseln, damit du wie viele verschiedene Besucher aussiehst, ist eine Form der Umgehung, und sie macht eine Blockade eher wahrscheinlicher als unwahrscheinlicher.
Wenn eine Seite Inhalte an Browser anders ausliefert als an reine HTTP-Clients, verwende für diese Seiten einen echten Browser und halte dieselbe Ratenbegrenzung ein. Das ist ein legitimer Weg, und er hält das Anfragemuster vernünftig.
Proxys mit Bedacht einsetzen
Ein Proxy ändert die Adresse, von der eine Anfrage kommt. Er ist ein Werkzeug für legitime Zwecke, etwa Tests aus einer bestimmten Region auf einer Seite, die du testen darfst, oder die Verteilung der Last auf deine eigene Infrastruktur. Er ist kein Weg, einer Grenze zu entkommen, die die Seite dir gesetzt hat. Das Format für einen Proxy ist das, das die Proxy-Task-Typen verwenden:
proxies = {
"http": "http://user:pass@proxy.example.net:8000",
"https": "http://user:pass@proxy.example.net:8000",
}
resp = session.get("https://example.com/products", proxies=proxies, timeout=30)
Die Wahl des Proxy-Typs ist eine eigene Frage, die in Residential- vs. Datacenter-Proxys und Rotierende Proxys fürs Scraping behandelt wird.
Wenn aus der Blockade ein Captcha wird
Manche Seiten beantworten ein Ratenproblem mit einem Captcha statt mit einer harten Sperre. Die sinnvolle Reihenfolge ist: anhalten, langsamer werden, die Regeln erneut prüfen und erst dann an eine Lösung denken. Bei PopularCaptcha-Widgets gibt die Live-API von Scarnox ein Token zurück, das du im Feld h-captcha-response absendest. Für andere Captcha-Typen prüfe die aktuelle Liste, denn reCAPTCHA, Cloudflare Turnstile, GeeTest, AWS WAF und Arkose kommen demnächst. Der ausführliche Leitfaden ist Web-Scraping und Captchas.
Wenn du auf einer Seite Blockaden siehst, liegt die Ursache fast immer im Anfragemuster. Captchas beim Scraping vermeiden beschreibt die Gewohnheiten, die das verhindern.
Verantwortungsvoll scrapen
- Prüfe
robots.txtund die Nutzungsbedingungen der Seite, bevor du anfängst, und folge den Pfaden und Verzögerungen, die sie verlangen. - Hör auf, wenn du ein 403 oder eine klare Aufforderung "nicht scrapen" erhältst. Versuche es nicht weiter.
- Halte deine Rate niedrig genug, dass ein normaler Besucher deinen Datenverkehr nicht bemerken würde.
- Erhebe keine personenbezogenen Daten, für die du keinen Grund hast, und behandle alle, die du erhebst, nach den Datenschutzregeln, die für dich gelten.
- Wenn du weit mehr Volumen brauchst, als eine Seite bequem ausliefert, bitte den Betreiber um einen Feed oder eine API.