Beheben Sie 429 Too Many Requests: Backoff, Budgets und IP-Verteilung

Ein 429 ist die einzige Sperre, die Ihnen genau sagt, wie Sie sie beheben können – wenn Sie die Antwort-Header lesen, anstatt einfach erneut zu versuchen. Hier ist die Arithmetik hinter sicherem Scraping-Durchsatz.

HTTP 429 Too Many Requests ist die ehrlichste Sperre, die Ihnen eine Website senden kann. Im Gegensatz zu einem 403 benennt es das Problem – Sie waren zu schnell – und liefert häufig die Lösung in einem Antwort-Header. Doch die Standardreaktion ist, den Aufruf in eine Wiederholungsschleife zu wickeln und zu hoffen, was ein lösbares Taktproblem in ein langsames, blockgenerierendes Chaos verwandelt. Dieser Leitfaden behandelt 429 als das, was es ist: ein arithmetisches Problem mit vier Hebeln. Lesen Sie die Antwort, halten Sie sich an das veröffentlichte Limit, ziehen Sie sich korrekt zurück, wenn Sie es überschreiten, und verteilen Sie die verbleibende Last auf Identitäten.

Was 429 bedeutet und wann es lügt

Ein Rate Limiter zählt Anfragen pro Identität – normalerweise eine IP-Adresse, manchmal ein API-Schlüssel oder Session-Cookie – innerhalb eines Zeitfensters. Überschreiten Sie die Schwelle, erhalten Sie 429 anstelle von Inhalten. Implementierungen unterscheiden sich: Token-Buckets geben ein festes Kontingent aus, das nach einem Zeitplan aufgefüllt wird, gleitende Fenster zählen über einen rollierenden Zeitraum statt über Minuten, und gestufte Systeme drosseln bei einem weichen Limit, bevor sie bei einem höheren hart blockieren. Welche Sie vorfinden, bestimmt, ob eine kurze Pause ausreicht oder ob Sie ein ganzes Fenster abwarten müssen.

Nun der Vorbehalt, der Stunden spart: ein 429 bei Ihrer ersten Anfrage ist kein Rate Limit. Es ist eine Bot-Antwort, die ein Rate-Limit-Kostüm trägt. Ein vielgelesener Stack Overflow-Thread beschreibt genau dies – der allererste Aufruf eines Scrapers gab eine Seite zurück, die "Misbehaving Content Scraper Please use robots.txt Your IP has been rate limited" zusammen mit dem 429 las. Nichts wurde überschritten; der Server entschied einfach, dass der Client ein Bot war und wählte diesen Code. Wenn Sie 429 sehen, bevor Sie ein Volumen gesendet haben, behandeln Sie es als Erkennungsproblem und arbeiten Sie die Header- und IP-Überprüfungen in unserem Leitfaden zu 403 Forbidden Errors stattdessen.

Lesen Sie die Antwort, bevor Sie Code ändern

Gut erzogene Server sagen Ihnen, wann Sie zurückkommen sollen. Retry-After enthält entweder eine Anzahl von Sekunden oder ein HTTP-Datum. Viele APIs fügen X-RateLimit-Limit (die Obergrenze), X-RateLimit-Remaining (was im aktuellen Fenster übrig ist) und X-RateLimit-Reset (wann es sich auffüllt) hinzu. Diese drei verwandeln reaktives Wiederholen in proaktives Taktgeben: Sie können vor der Sperre langsamer werden, anstatt danach.

import requests

r = requests.get("https://target.example/api/items", timeout=20)
print(r.status_code)
for h in ("Retry-After", "X-RateLimit-Limit", "X-RateLimit-Remaining", "X-RateLimit-Reset"):
    if h in r.headers:
        print(f"{h}: {r.headers[h]}")

# No headers at all? The limit is undocumented - measure it:
# send a slow ramp (1 req/s, then 2, then 4) and note where 429 starts.

Wenn nichts Nützliches zurückkommt, messen Sie das Limit selbst mit einer Rampe: führen Sie eine Anfrage pro Sekunde für eine Minute aus, dann zwei, dann vier, und zeichnen Sie die Rate auf, bei der 429s erscheinen. Zehn Minuten Messung schlagen eine Woche Raten, und die Zahl, die Sie finden, wird zum Budget, auf dem alles andere aufgebaut ist.

Bänderdiagramm, das sichere, marginale und 429-auslösende Anfragelücken gegen ein Limit von 100 Anfragen pro Minute zeigt
Die gesamte Berechnung: 60 Sekunden geteilt durch das veröffentlichte Limit, dann Puffer für Netzwerk-Jitter hinzufügen.

Die Taktarithmetik

Nehmen Sie das dokumentierte Limit und teilen Sie. Ein Limit von 100 Anfragen pro Minute bedeutet 60 / 100 = 0,6 Sekunden zwischen den Anfragen als absolutes Minimum – und ein Minimum ist kein Ziel. Die Netzwerklatenz variiert, Ihre Uhr und die des Servers stimmen nicht überein, und ein Burst an der Fenstergrenze kann Ihre scheinbare Rate verdoppeln. Zielen Sie auf 70-80% des Limits: ungefähr 0,8 Sekunden pro Anfrage in diesem Beispiel, was Ihnen immer noch 75 Seiten pro Minute gibt.

Die Gleichzeitigkeit folgt aus derselben Zahl. Wenn Sie 1,25 Anfragen pro Sekunde möchten und jede Anfrage 2 Sekunden Round-Trip dauert, benötigen Sie 1,25 x 2 = 2,5 Anfragen in der Luft – also ein Semaphor von 3, nicht die 50, die Ihr asynchroner Code standardmäßig verwendet. Ungebremstes asynchrones Fan-Out ist die häufigste Ursache für 429s: hundert Coroutinen, die gleichzeitig gestartet werden, kommen als ein sofortiger Burst an, egal wie höflich der Durchschnitt aussieht. Wenn Sie mit asyncio scrapen, sind die Semaphor-Muster in async Python scraping with httpx and aiohttp die Lösung.

Backoff, das funktioniert: exponentiell, begrenzt, mit Jitter

Wenn Sie auf ein 429 stoßen, beachten Sie Retry-After, falls vorhanden. Andernfalls beginnen Sie mit einer Sekunde und verdoppeln – 1, 2, 4, 8, 16 – bis zu einer festen Obergrenze, damit ein kaputtes Ziel Ihre Warteschlange nicht für immer blockieren kann. Fügen Sie dann Jitter hinzu. Ohne Randomisierung versucht jeder Arbeiter, der gleichzeitig auf die Wand gestoßen ist, gleichzeitig erneut, wodurch der Burst reproduziert wird, der das Problem verursacht hat.

import random, time, requests

def get_with_backoff(session, url, max_tries=6, cap=120.0):
    for attempt in range(max_tries):
        r = session.get(url, timeout=20)
        if r.status_code != 429:
            return r

        ra = r.headers.get("Retry-After", "")
        wait = float(ra) if ra.isdigit() else 2.0 ** attempt   # 1, 2, 4, 8, 16, 32
        wait = min(wait, cap)
        wait += random.uniform(0, wait * 0.3)                   # jitter: break the lockstep

        time.sleep(wait)
    raise RuntimeError(f"still 429 after {max_tries} attempts: {url}")

Noch besser, schließen Sie den Kreis. Additive-Increase/Multiplicative-Decrease gibt Ihnen einen Scraper, der das Limit selbst findet und knapp darunter bleibt: erhöhen Sie die Rate, während die Antworten sauber sind, halbieren Sie sie sofort, wenn ein 429 eintrifft. Halten Sie einen Taktgeber pro Domain – Limits sind pro Host, und ein aggressives Ziel sollte die anderen vierzig nicht verlangsamen.

class Pacer:
    """One per domain. Additive increase, multiplicative decrease."""
    def __init__(self, rps=2.0, floor=0.2, ceiling=8.0):
        self.rps, self.floor, self.ceiling = rps, floor, ceiling

    def ok(self):          # clean response: creep faster
        self.rps = min(self.ceiling, self.rps + 0.05)

    def throttled(self):   # 429: halve immediately
        self.rps = max(self.floor, self.rps / 2)

    @property
    def gap(self):
        return 1.0 / self.rps

Lastverteilung: das Budget ist pro Identität, nicht pro Projekt

Sobald Sie korrekt takten und dennoch mehr Durchsatz benötigen, bleibt nur noch der Hebel der Identitäten. Da der Zähler an Ihre IP gebunden ist, geben Ihnen N Exit-IPs N-mal das Budget – die Arithmetik ist so einfach. Wenn eine Seite 60 Anfragen pro Minute pro Adresse toleriert und Sie 1.200 Seiten pro Minute benötigen, sind das 20 gleichzeitige Exits, die bequem unter dem Limit laufen, nicht ein Exit, der zwanzigmal darüber liegt.

Dafür sind rotierende Proxies tatsächlich gedacht. Ein rotierendes Gateway gibt jeder Anfrage eine andere Wohn-IP aus einem Pool von über 90 Millionen Adressen in über 200 Ländern, sodass die Zähler pro IP nie voll werden. Zwei Regeln machen den Unterschied zwischen Lastverteilung und Poolverbrennung: Halten Sie die Rate pro IP auch nach der Rotation unter dem Limit (Rotation multipliziert Ihr Budget, es entfernt es nicht) und verwenden Sie Sticky-Sessions für jeden Ablauf, der mehrere Anfragen umfasst – ein Login, ein Warenkorb, ein paginiertes Ergebnisset – damit die Sitzung nicht mitten im Weg unterbrochen wird. Wenn Sie dieselbe IP für ein paar Minuten und danach eine neue benötigen, sind die Kompromisse in Sticky versus Rotating Sessions dargelegt.

Multiplizieren Sie Ihr Rate-Budget mit Wohn-IPs

Statistik-Panel, das die Schlüsselzahlen zur Vermeidung von HTTP 429-Fehlern zeigt: 600 ms Mindestabstand, exponentielles Backoff, 50 Prozent Rate-Kürzung und pro-IP-Budgets
Vier Zahlen steuern das gesamte System. Leiten Sie sie aus den Limits des Ziels ab, niemals aus Optimismus.

Günstiger als mehr IPs: weniger Anfragen senden

Bandbreitendisziplin zahlt sich doppelt aus – weniger Anfragen bedeuten weniger 429s und eine kleinere Rechnung, was dasselbe Argument ist, das wir in Proxy-Bandbreitenkosten senken machen. Und wenn Sie überhaupt keine Taktinfrastruktur aufbauen möchten, absorbiert die QuantumProxies Scraper API Wiederholungen, Rotation und pro-Domain-Drosselung hinter einem Endpunkt, der Markdown, JSON oder HTML zurückgibt.

Häufig gestellte Fragen

Wie vermeide ich HTTP error 429 too many requests in Python?

Setzen Sie eine bewusste Lücke zwischen Anfragen basierend auf dem veröffentlichten Limit des Ziels, begrenzen Sie die Gleichzeitigkeit mit einem Semaphor, das auf Rate mal Latenz ausgelegt ist, beachten Sie Retry-After, wenn es erscheint, und wiederholen Sie mit exponentiellem Backoff plus Jitter. Wenn Sie danach mehr Durchsatz benötigen, verteilen Sie Anfragen auf rotierende Proxy-IPs, anstatt die Lücke zu verkürzen.

Wie lange sollte ich nach einem 429 warten?

Genau so lange, wie Retry-After sagt, wenn der Server es sendet – es kann eine Sekundenanzahl oder ein HTTP-Datum sein. Ohne diesen Header beginnen Sie mit einer Sekunde und verdoppeln bei jedem nachfolgenden 429 bis zu einer Obergrenze von ein oder zwei Minuten, wobei Sie zufälligen Jitter hinzufügen, damit parallele Arbeiter nicht gleichzeitig erneut versuchen.

Beheben Proxies 429-Fehler?

Sie multiplizieren Ihr Budget, sie entfernen das Limit nicht. Da Zähler an die Client-IP gebunden sind, hält das Verteilen eines Laufs auf viele Wohn-Exits jede Adresse unter dem Schwellenwert. Aber ein Pool, der zehnmal über dem Pro-IP-Limit gehämmert wird, wird immer noch 429s sammeln – und seinen Ruf schädigen. Taktieren Sie zuerst, dann rotieren Sie.

Ist ein 429 dasselbe wie ein Verbot?

Nein. Ein 429 ist von Natur aus temporär und wird zurückgesetzt, wenn das Fenster zurückgesetzt wird, was es von einem 403-Identitätssperre unterscheidet. Es wiederholt zu ignorieren, ist, wie es dauerhaft wird: anhaltendes Überschreiten ist genau das Signal, das eine Drosselung in ein längerlebiges IP-Verbot verwandelt.

Warum bekomme ich 429 bei der allerersten Anfrage?

Weil nichts tatsächlich gezählt wurde. Einige Server geben 429 an jeden Client zurück, den sie als Bot betrachten, unabhängig vom Volumen – der Statuscode ist nur ihre gewählte Antwort. Überprüfen Sie den Antworttext: wenn er robots.txt, Scraper oder eine Firewall erwähnt, korrigieren Sie Ihre Header, TLS-Fingerabdruck und Exit-IP anstatt Ihr Taktverhalten.

Behandeln Sie Rate Limits als ein Budget, das Sie bewusst ausgeben. Messen Sie die Obergrenze, laufen Sie bei 70-80% davon, ziehen Sie sich mit Jitter zurück, wenn Sie es überschreiten, und kaufen Sie mehr Identitäten erst, wenn das Taktverhalten stimmt. In dieser Reihenfolge durchgeführt, hören 429s auf, eine Fehlerklasse zu sein, und werden zu einer Zahl in einer Konfigurationsdatei.

Holen Sie sich rotierende Proxies und hören Sie auf, gegen Rate Limits zu kämpfen