Kurze Antwort
Wie sollte ein Scraper mit 403-, 429- und CAPTCHA-Antworten umgehen?
Behandle sie als Signale, nicht als Hindernisse. Bei einem 429 warte Retry-After und reduziere die Rate auf diesem Host. Bei einem 403 versuche es nach einer Pause einmal erneut, dann stoppe und überprüfe die Regeln der Website. Bei einem CAPTCHA stoppe diesen Host: löse das CAPTCHA nicht automatisch. CrawlRelay Residential-Proxys, von 0,50 $/GB, verteilen die Last und legen den Standort fest; sie umgehen nicht die Entscheidungen der Website. Ohne KYC. Mit Krypto bezahlen.
Die drei Signale auf einen Blick
| 429 Zu viele Anfragen | Sie sind zu schnell. Beachten Sie Retry-After, treten Sie zurück, reduzieren Sie die gleichzeitigen Anfragen pro Host. |
|---|---|
| 403 Forbidden | Diese Anfrage wird abgelehnt. Nach einer Pause einmal erneut versuchen, dann stoppen und die Regeln prüfen. |
| CAPTCHA oder Herausforderungsseite | Die Website möchte wissen, ob Sie ein Mensch sind. Stoppen Sie den Host und verlangsamen Sie das Tempo. |
| Standard für Crawl-Regeln | robots.txt, RFC 9309; Crawl-delay ist eine gängige Erweiterung |
| Was wir nicht unterstützen | CAPTCHA-Lösungen, Stealth-Plugins, Fingerabdruck-Spoofing |
Was sagt jedes Signal meinem Crawler?
- 429 ist das höflichste Signal: der Inhalt ist verfügbar, aber nicht so schnell, wie Sie ihn abrufen wollen. RFC 6585 definiert es, oft mit einem
Retry-After-Header, der angibt, wann Sie es erneut versuchen sollen. - 403 ist eine Ablehnung dieser Anfrage. Es kann beheizbar sein (falsches Land, fehlende Header, zu schnell) oder endgültig (die Website erlaubt keinen automatisierten Zugriff auf diesen Inhalt).
- Ein CAPTCHA oder eine Herausforderungsseite, oft mit Status 403 oder 503, bedeutet, dass das Bot-Management der Seite Ihren Traffic anzweifelt. Es ist eine Eskalation: der Schritt nach ignorierten 429er.
Alle drei sind zunehmende Signale. Seiten, die ihre 429 ignorieren, eskalieren zu 403 und Challenges, dann zu langen Sperren ganzer IP-Bereiche, was allen Nutzern dieser Bereiche schadet.
Was soll mein Crawler bei jedem Signal tun?
| Signal | Erste Reaktion | Wenn es weiterhin auftritt | Stoppen bei |
|---|---|---|---|
| 429 | Warten auf Retry-After oder exponentiell mit Jitter zurückgehen | Reduziere die gleichzeitigen Anfragen auf diesem Host um die Hälfte | Retry-After wächst weiter oder 429 treten bei nur einer Anfrage pro Zeit auf |
| 403 | Einmalig nach einer Pause erneut versuchen, gleiches Land | Mit einem Browser aus dem gleichen Land vergleichen; robots.txt und Nutzungsbedingungen prüfen | Zweiter 403 bei gleichem URL-Muster |
| CAPTCHA / Herausforderung | Host für mehrere Minuten pausieren | Mit deutlich geringerer Rate fortsetzen | Die Herausforderung tritt bei niedriger Rate erneut auf: die Website will keinen automatisierten Zugriff |
| 503 mit Retry-After | Warten wie angegeben | Host pausieren | Die meisten Anfragen schlagen länger als ein paar Minuten fehl |
Wie baue ich einen Crawler, der richtig reagiert?
Setzen Sie die Regeln im Fetcher um, nicht in jedem Spider. Dieser sendet nur eine Anfrage pro Host gleichzeitig, beachtet robots.txt und dessen Crawl-delay, wartet auf Retry-After und stellt nach drei aufeinanderfolgenden Ablehnungen bei einem Host die Anfragen ein. Er behandelt 4xx in robots.txt als Erlaubnis und 5xx als komplettes Verbot, wie RFC 9309 es vorschreibt.
import time
import urllib.robotparser
from urllib.parse import urlsplit
import requests
PROXY = "http://USERNAME-country-us:[email protected]:7777"
USER_AGENT = "ExampleCrawler/1.0 (+https://example.com/crawler-info)"
class PoliteFetcher:
"""One request at a time per host; robots.txt, Crawl-delay and Retry-After honoured."""
def __init__(self, min_interval=1.0, max_refusals=3):
self.min_interval, self.max_refusals = min_interval, max_refusals
self.http = requests.Session()
self.http.proxies = {"http": PROXY, "https": PROXY}
self.http.headers["User-Agent"] = USER_AGENT
self.robots, self.next_time, self.refusals = {}, {}, {}
def _robots(self, root):
if root not in self.robots:
rp = urllib.robotparser.RobotFileParser(root + "/robots.txt")
try:
r = self.http.get(root + "/robots.txt", timeout=(10, 30))
if r.status_code >= 500:
rp.parse(["User-agent: *", "Disallow: /"]) # unreachable: assume disallow
else:
rp.parse(r.text.splitlines() if r.status_code == 200 else []) # 4xx: allowed
except requests.RequestException:
rp.parse(["User-agent: *", "Disallow: /"])
self.robots[root] = rp
return self.robots[root]
def get(self, url):
scheme, host = urlsplit(url)[:2]
if self.refusals.get(host, 0) >= self.max_refusals:
return None # this host said no: stop asking
rp = self._robots("%s://%s" % (scheme, host))
if not rp.can_fetch(USER_AGENT, url):
return None
delay = max(self.min_interval, rp.crawl_delay(USER_AGENT) or 0)
wait = self.next_time.get(host, 0) - time.monotonic()
if wait > 0:
time.sleep(wait)
r = self.http.get(url, timeout=(10, 30))
pause = delay
if r.status_code in (429, 503):
retry_after = r.headers.get("Retry-After", "")
pause = max(delay, int(retry_after) if retry_after.isdigit() else 60)
refused = r.status_code in (403, 429) or "captcha" in r.text[:5000].lower()
self.refusals[host] = self.refusals.get(host, 0) + 1 if refused else 0
self.next_time[host] = time.monotonic() + pause
return r
fetcher = PoliteFetcher()
resp = fetcher.get("https://example.com/")
print(resp.status_code if resp is not None else "skipped")Was behebt einen 403 auf faire Weise?
Mehrere Ursachen für 403 liegen bei Ihnen und eine Korrektur ist fair:
- Falsches Land. Viele Seiten bedienen nur eine Region. Zielgerichtet das Land mit
-country-<code>auswählen. - Unvollständige Header. Senden Sie
Accept,Accept-Languageund einen ehrlichen User-Agent mit Kontakt-URL. Ein Browser-ähnlicher User-Agent auf einem einfachen HTTP-Client passt nicht zusammen und wird oft abgelehnt. - Eigenes Tempo. Ein 403, das nach N Anfragen kommt, ist ein Rate-Problem; verlangsamen Sie sich.
Was keine Lösung ist: User-Agents rotieren, um wie viele unterschiedliche Personen auszusehen, Browser-Fingerprints fälschen oder IPs wechseln, um eine absichtliche Sperre zu umgehen. Wenn eine Website Hosting-Bereiche filtert, um automatisierten Traffic auszuschließen, macht eine Residential Proxy-IP den Zugriff nicht erlaubt.
Warum nicht einfach die CAPTCHAs lösen?
Weil ein CAPTCHA die Webseite ist, die eine Frage stellt, die Sie falsch beantworten würden. Automatisiertes Lösen verwandelt einen höflichen Crawler in ein Werkzeug, das darauf ausgelegt ist, eine Zugriffskontrolle zu umgehen, was Ihr rechtliches Risiko erhöht: Die US-Fälle von 2026 bezüglich Such-Scraping, Google v. SerpApi und Reddit v. SerpApi sowie andere basieren auf Behauptungen, dass die Angeklagten ein Anti-Bot-System unter Umgehung der DMCA-Anti-Circumvention-Regel umgangen haben. Gerichte haben die Frage noch nicht geklärt, aber das Risiko ist real.
CrawlRelay unterstützt das Lösen von CAPTCHA oder die Umgehung der Bot-Erkennung nicht, und seine Acceptable Use Policy verbietet dies ausdrücklich am Gateway. Wenn Sie Daten hinter einer Herausforderung benötigen, fragen Sie die Seite um Zugang, nutzen Sie deren API oder lizenzieren Sie die Daten.
Wann sollte ich stattdessen die Seite kontaktieren?
Wenn Sie mehr benötigen als die Standardlimits erlauben. Viele Seiten bieten eine API, einen Datenfeed, ein Partnerprogramm oder einfach ein höheres Limit für einen Crawler, der sich identifiziert und seinen Zweck erklärt. Fügen Sie eine Kontakt-URL in Ihren User Agent ein, pflegen Sie eine Seite, die Ihren Crawler und die Opt-out-Möglichkeiten beschreibt, und reagieren Sie schnell auf Missbrauchsmeldungen. Ein erreichbarer Crawler erhält Warnungen bevor es zu Sperren kommt.
403, 429 und CAPTCHAs: Fragen
Stoppen Residential-Proxys CAPTCHAs?
Verlassen Sie sich nicht darauf. Ein Residential Proxy ändert, welche IP die Seite sieht, aber nicht, wie sich Ihr Crawler verhält: CAPTCHAs aufgrund Ihres Tempos oder Verhaltens bleiben bestehen, und das ist beabsichtigt. Wenn Herausforderungen trotz niedriger Anfragerate fortbestehen, will die Seite keinen automatisierten Zugriff auf diese Inhalte.
Wie lange soll ich nach einem 429 ohne Retry-After warten?
Starten Sie mit ein paar Sekunden und verdoppeln Sie die Wartezeit nach jedem neuen 429, mit einem zufälligen Zusatz und einer Obergrenze von etwa einer Minute. Wenn Anfragen wieder erfolgreich sind, setzen Sie mit einer niedrigeren Rate als vor dem 429 fort und erhöhen diese langsam, solange die Fehlerquote stabil bleibt.
Ist Rotation der IPs zur Vermeidung von Ratenbegrenzungen erlaubt?
Rotation verteilt die Last auf verschiedene Exits und ermöglicht die Auswahl von Standorten, was normal ist. Die Verwendung von Rotation, um unter einem Pro-IP-Limit zu bleiben und dabei eine von der Seite abgelehnte Rate aufrechtzuerhalten, ist Umgehung. Die meisten Nutzungsbedingungen verbieten dies, ebenso unsere Acceptable Use Policy.
Welchen User Agent soll mein Scraper senden?
Ihren eigenen: einen Namen, eine Version und eine URL, die den Crawler und die Kontaktmöglichkeiten erklärt, zum Beispiel ExampleCrawler/1.0 (+https://example.com/crawler-info). Verwenden Sie nicht die Namen anderer Crawler wie Googlebot oder GPTBot.
Quellen (4)
- RFC 9309: Robots Exclusion Protocol — IETF (2022-09)
- RFC 6585: Zusätzliche HTTP-Statuscodes (429) — IETF (2012-04)
- Reddit v. SerpApi LLC — Loeb & Loeb (2026-08)
- Google v. SerpApi: Das Gericht hat unserem Antrag auf Abweisung stattgegeben — SerpApi (2026-07-21)
Residential-Proxys für höfliche Crawler
1,50 $ für 1 GB, 0,50 $/GB ab 50 GB.