Ohne KYC – keine ID, kein Selfie, keine Dokumente. Mit Krypto bezahlen: BTC, USDT, USDC, ETH, SOL, LTC
Sprache: Deutsch
API-Schlüssel erhalten

Docs · Fehler

Fehler, robots.txt-Ablehnungen und Retries

Jeder Fehler hat einen HTTP-Status, ein stabiles code und eine lesbare message. Keiner von ihnen verbraucht einen Credit. Manche sind einen Retry wert; die Ablehnungen, die von einer Seite kommen, sind endgültig, und wir umgehen sie nie.

Zuletzt aktualisiert: · 5 Min. Lesezeit

Kurze Antwort

Was bedeuten die WebReaderAPI-Fehlercodes und welche sollte ich wiederholen?

WebReaderAPI Fehler kommen in drei Gruppen, und keiner wird jemals berechnet. Anfrageprobleme (invalid_url, invalid_api_key, insufficient_credits) erfordern eine Korrektur auf Ihrer Seite. Seiten-Entscheidungen (blocked_by_robots, blocked_by_site_policy, target_refused) sind endgültig. Vorübergehende Fehler (fetch_failed, fetch_timeout, concurrency_limit) können mit Backoff wiederholt werden. Credits beginnen bei 0,07 $/1K Seiten, zahlbar mit Krypto ohne KYC.

Welche Fehlercodes kann die API zurückgeben?

Der Body ist immer {"error": {"code", "message"}}, plus target_status, wenn die Ablehnung von der Seite kam.

HTTPcodeUrsacheErneut versuchen?
400invalid_urlKein http oder https, zu lang oder eine private, lokale oder Cloud-Metadaten-AdresseNein: URL korrigieren
400invalid_parameterEin Parameter hat einen Wert außerhalb seiner Liste oder seines BereichsNein: Anfrage korrigieren
401invalid_api_keyAPI-Schlüssel fehlt, ist falsch oder wurde widerrufenNein: API-Schlüssel prüfen
402insufficient_creditsIhr Guthaben hat keine Credits mehrNach dem Kauf eines Pakets
403blocked_by_robotsDie robots.txt der Webseite erlaubt die Seite WebReaderAPI oder allen Robots nichtNein: endgültig
403blocked_by_site_policyDie Webseite deklariert Content-Signal: ai-input=noNein: endgültig
422unsupported_contentEin Typ, den wir nicht lesen (Video, Archiv), oder eine zu große DateiNein
429concurrency_limitZu viele Ihrer Anfragen laufen gleichzeitigJa, mit Backoff
502target_refusedDie Webseite hat abgelehnt: 403, 429, eine Challenge-Seite oder eine Login-Wand; der Status steht in target_statusNein: endgültig
502fetch_failedDNS-, TLS- oder Verbindungsfehler, oder die Webseite hat mit 404 oder 410 geantwortetEin- oder zweimal, mit Backoff
504fetch_timeoutDie Webseite hat nicht innerhalb von timeout geantwortetJa, mit Backoff oder einem längeren Timeout

Warum sind robots.txt und Ablehnungen durch Webseiten endgültig?

Weil sie die Entscheidung des Webseiten-Betreibers sind und WebReaderAPI dafür gebaut ist, sie zu befolgen. Wir respektieren robots.txt: Unser Crawler identifiziert sich als WebReaderAPI, befolgt die Regeln, die für ihn oder für alle Roboter geschrieben sind, und liest keine Seite, die eine Website nicht erlaubt. Verweigerte Seiten werden nicht abgerechnet. Wenn eine Website in ihrer robots.txt Content-Signal: ai-input=no deklariert, lesen wir ihre Seiten nicht für Sie.

Wenn eine Webseite eine Anfrage auf andere Weise abweist, mit einem 403, einem 429, einer Challenge-Seite oder einem Login-Formular, erhalten Sie target_refused und den Status der Webseite selbst in target_status. Wenn eine Website unsere Suchanfrage ablehnt, geben wir ihre Antwort zurück: Wir lösen nie CAPTCHAs, melden uns nie in Konten an und versuchen nie, eine Sperre oder eine Paywall zu umgehen. Dieselbe URL eine Minute später erneut zu versuchen, liefert meist dieselbe Antwort. Behandeln Sie diese Codes daher als Ergebnis, nicht als Fehler: protokollieren und weiter.

Wie prüfe ich, warum eine Seite abgelehnt wurde?

Öffnen Sie die /robots.txt der Webseite und suchen Sie nach einer Gruppe, die WebReaderAPI nennt, oder nach der Gruppe *, die für alle Robots gilt. Eine Zeile Disallow, die zum Pfad passt, erklärt ein blocked_by_robots. Eine Zeile wie Content-Signal: ai-input=no erklärt ein blocked_by_site_policy.

Wir bewahren eine Kopie jeder robots.txt höchstens 24 Stunden auf. Wenn eine Webseite gerade einen Bereich für Robots geöffnet hat, kann die Änderung bis zu einem Tag brauchen, bis sie greift. Webseiten-Betreiber können auf unserer Crawler-Seite nachlesen, wie sich unser Crawler verhält und wie man ihn erlaubt oder blockiert.

Wie sollte ich temporäre Fehler erneut versuchen?

Versuchen Sie nur concurrency_limit, fetch_timeout und ein- oder zweimal fetch_failed erneut. Warten Sie vor jedem neuen Versuch und verdoppeln Sie die Wartezeit jedes Mal, mit etwas zufälligem Jitter, damit parallele Worker nicht gleichzeitig erneut versuchen. Hören Sie nach 4 oder 5 Versuchen auf.

Bei concurrency_limit ist es besser, weniger Anfragen gleichzeitig zu senden: Jedes Konto hat ein Limit dafür, wie viele Seiten es gleichzeitig liest; Ihr Dashboard zeigt es an, und der Support kann es erhöhen. Bei fetch_timeout erhöhen Sie timeout auf bis zu 60 Sekunden, bevor Sie eine langsame Webseite erneut versuchen. Wiederholungen kosten nichts, denn ein fehlgeschlagener Versuch wird nie berechnet.

Python: nur die Fehler erneut versuchen, die sich ändern können
import os
import random
import time

import requests

API = "https://webreaderapi.com/api/v1/read"
HEADERS = {"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]}
RETRY = {"concurrency_limit", "fetch_timeout", "fetch_failed"}
FINAL = {"blocked_by_robots", "blocked_by_site_policy", "target_refused", "unsupported_content"}


def read_page(url, attempts=5, **options):
    wait = 1.0
    for attempt in range(1, attempts + 1):
        resp = requests.get(API, headers=HEADERS, params={"url": url, **options}, timeout=75)
        if resp.status_code == 200:
            return resp.json()
        error = resp.json().get("error", {})
        code = error.get("code", "unknown")
        if code in FINAL:
            return {"url": url, "skipped": code, "target_status": error.get("target_status")}
        if code not in RETRY or attempt == attempts or (code == "fetch_failed" and attempt >= 3):
            raise RuntimeError(f"{code}: {error.get('message')}")
        time.sleep(wait + random.uniform(0, wait / 2))
        wait = min(wait * 2, 30)
    raise RuntimeError("unreachable")


if __name__ == "__main__":
    print(read_page("https://example.com/blog/first-post", max_chars=20000).get("title"))
Node.js: dieselbe Regel mit exponentiellem Backoff
const RETRY = new Set(['concurrency_limit', 'fetch_timeout', 'fetch_failed']);
const FINAL = new Set(['blocked_by_robots', 'blocked_by_site_policy', 'target_refused', 'unsupported_content']);
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

export async function readPage(url, options = {}, attempts = 5) {
  let wait = 1000;
  for (let attempt = 1; attempt <= attempts; attempt++) {
    const params = new URLSearchParams({ url, ...options });
    const res = await fetch(`https://webreaderapi.com/api/v1/read?${params}`, {
      headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}` },
    });
    const body = await res.json();
    if (res.ok) return body;
    const code = body.error?.code ?? 'unknown';
    if (FINAL.has(code)) return { url, skipped: code, target_status: body.error.target_status };
    if (!RETRY.has(code) || attempt === attempts) throw new Error(`${code}: ${body.error?.message}`);
    await sleep(wait + Math.random() * (wait / 2));
    wait = Math.min(wait * 2, 30000);
  }
}

Was ist mit Fehlern innerhalb eines Batch oder Crawls?

Ein Job stoppt nicht, weil eine Seite fehlschlägt. Diese Seite erscheint in results als {url, error} mit denselben Codes wie oben, und sie kostet nichts. Ein Crawl, der auf einen Abschnitt blocked_by_robots stößt, liest einfach den Rest der Website.

Zählen Sie am Ende eines Jobs die Fehlercodes. Viele target_refused auf einer Website bedeuten, dass die Website automatisierte Reader nicht akzeptiert; viele fetch_timeout bedeuten, dass sie langsam ist, und ein längeres timeout in den Job-Optionen kann helfen.

Fehler: häufige Fragen

Wird mir eine Seite berechnet, die robots.txt blockiert?

Nein. 1 Credit = 1 gelesene Seite ohne Browser; 2 Credits, wenn die Seite einen Browser braucht, um JavaScript auszuführen. Eine Suchanfrage, die fehlschlägt oder die eine robots.txt einer Website verweigert, wird nicht abgerechnet. Dasselbe gilt für jeden anderen Fehler auf dieser Seite.

Können Sie eine Seite lesen, die Ihren Crawler blockiert, wenn ich es verlange?

Nein. Wir folgen der Entscheidung des Website-Betreibers, und die Richtlinie ist für jeden Kunden gleich. Wenn Sie die Website besitzen, fügen Sie eine Regel für WebReaderAPI in Ihre robots.txt ein; die Crawler-Seite zeigt, wie.

Warum bekomme ich fetch_failed für eine Seite, die existiert?

Die Website war möglicherweise ausgefallen, hat eine TLS-Verbindung nur langsam akzeptiert oder gibt automatisierten Clients 404 zurück. Versuchen Sie es ein- oder zweimal mit Backoff erneut. Wenn es weiterhin fehlschlägt, prüfen Sie die Adresse in einem Browser.

Was sollte mein Agent dem Nutzer nach einer Ablehnung sagen?

Etwas Einfaches, etwa dass die Website das automatisierte Lesen dieser Seite nicht erlaubt. Lassen Sie das Modell dann andere Quellen nutzen. Den Fehlercode als Tool-Ergebnis zurückzugeben, reicht für die meisten Modelle.

Ab 0,07 $/1K Seiten · ohne KYC

API-Schlüssel erhalten