Scarnox · Blog

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:

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:

  1. Schau dir die erste fehlschlagende URL und ihren Statuscode an. Eine Blockade beginnt meist an einem bestimmten Punkt, nicht zufällig.
  2. Vergleiche die Anfragerate in den Minuten vor dem ersten Fehler. Ein Schwall ist die häufigste Ursache.
  3. Prüfe, ob der Fehler an einen Pfad, einen Bereich oder eine Tageszeit gebunden ist.
  4. 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.
  5. 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

Nächste Schritte