Fehlerbehandlung
Crawling im großen Maßstab bedeutet, dass Fehler passieren. Wenn Sie von Anfang an dafür bauen, verbringen Sie Ihre Zeit mit dem Ausliefern von Features statt mit dem Babysitten von Retries.
Drei Fehlerklassen
Jeder Crawlbase-Fehler fällt in einen von drei Buckets, und jeder erfordert eine andere Reaktion.
429, 500, 503, 522, 599. Immer mit Backoff erneut versuchen.404, 410, 451. Nicht erneut versuchen - die Seite existiert tatsächlich nicht oder ist nicht zugänglich. Markieren Sie die URL als fehlgeschlagen und machen Sie weiter.401, 402, 403, 422. Erneutes Versuchen hilft nicht - korrigieren Sie den Request, das Token oder den Account.Produktions-Retry-Muster
Das Muster, das unter Last hält: exponentielles Backoff mit vollem Jitter, begrenzte Versuche und ein Dead-Letter-Ziel für endgültige Fehler.
import time, random, logging
from crawlbase import CrawlingAPI
api = CrawlingAPI({'token': 'YOUR_TOKEN'})
log = logging.getLogger('crawler')
TRANSIENT = {429, 500, 503, 522, 599}
TERMINAL = {401, 402, 403, 404, 410, 422, 451}
def crawl(url, max_attempts=5, base=0.5, cap=30):
for attempt in range(max_attempts):
res = api.get(url)
status = res['status_code']
if status == 200 and res['pc_status'] == 200:
return res
if status in TERMINAL or res['pc_status'] in TERMINAL:
log.warning(f'Terminal error {status}/{res['pc_status']} for {url}')
raise PermanentFailure(url, status)
# Transient - sleep with full jitter, then retry
wait = min(cap, base * (2 ** attempt))
wait = random.uniform(0, wait)
log.info(f'Attempt {attempt+1} got {status}; sleeping {wait:.2f}s')
time.sleep(wait)
raise RuntimeError(f'Exhausted retries for {url}')
class PermanentFailure(Exception): passconst { CrawlingAPI } = require('crawlbase');
const api = new CrawlingAPI({ token: process.env.CRAWLBASE_TOKEN });
const TRANSIENT = new Set([429, 500, 503, 522, 599]);
const TERMINAL = new Set([401, 402, 403, 404, 410, 422, 451]);
async function crawl(url, { maxAttempts = 5, base = 500, cap = 30000 } = {}) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const res = await api.get(url);
const status = res.statusCode;
if (status === 200 && res.pcStatus === 200) return res;
if (TERMINAL.has(status) || TERMINAL.has(res.pcStatus)) {
throw new Error(`Permanent failure \${status} for \${url}`);
}
const wait = Math.random() * Math.min(cap, base * 2 ** attempt);
await new Promise(r => setTimeout(r, wait));
}
throw new Error(`Exhausted retries for \${url}`);
}Dead-Letter-Queue
Wenn Retries erschöpft sind, lassen Sie die URL nicht stillschweigend fallen. Schieben Sie sie an einen Ort, an dem ein Mensch sie überprüfen kann.
- Für Crawler API-Nutzer: Fehler werden automatisch bis zu Ihrer konfigurierten Anzahl wiederholt und dann mit den Fehler-Metadaten an Ihren Webhook geliefert. Keine DLQ zu bauen.
- Für Direkt-API-Nutzer: Schreiben Sie bei endgültigem Fehler die URL + Status + letzten Response-Body in eine separate Queue oder Tabelle. Wöchentlich überprüfen.
Begrenzen Sie Retries auf etwa 5. Eine URL, die 5 Mal hintereinander fehlschlägt, wird mit ziemlicher Sicherheit auch 50 Mal fehlschlagen. Sparen Sie die Zyklen für neue Arbeit.
Was Sie überwachen sollten
Die vier Signale, die jedes Crawlbase-nutzende System darstellen sollte:
| Signal | Wo es herkommt | Alert wenn |
|---|---|---|
| Erfolgsrate | pc_status == 200 / gesamt | < 95 % anhaltend für 10 Min |
| P95-Latenz | Request-Dauer | > 15s anhaltend |
| 429-Rate | HTTP-Statushistogramm | > 5% anhaltend - Concurrency erhöhen |
| Retry-Anzahl-Verteilung | Ihre Retry-Schleife | P95 > 2 - irgendetwas verschlechtert sich upstream |
Taggen Sie jede Metrik mit der Zieldomain, damit Sie erkennen können, wenn eine einzelne Site Ihre Gesamtwerte vergiftet.
Retries sicher machen
Crawlbase-Requests sind von Natur aus idempotent - ein GET auf dieselbe URL mit demselben Token liefert jedes Mal die gleiche Art von Ergebnis. Sie können beliebig oft erneut versuchen, ohne sich um doppelte Seiteneffekte sorgen zu müssen.
Zwei Hinweise:
- Async + store: Wenn Sie
&async=true&store=trueverwendet haben, verbraucht jeder Retry ein Credit und erzeugt eine neuerid. Deduplizieren Sie bei Bedarf auf Ihrer Seite. - Webhooks: Crawler API-Webhooks können bei Fehlern mehrfach zugestellt werden. Machen Sie Ihren Webhook-Handler idempotent über
rid.