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

Docs · Jobs

Batch- und Crawl-API: viele URLs oder eine ganze Website lesen

Zwei Endpoints starten Hintergrund-Jobs: /batch für eine Liste mit bis zu 100 URLs, /crawl für eine Website. Beide liefern eine Job-ID; die Seiten holen Sie sich von /jobs/{job_id}, jeweils eine Seite Ergebnisse.

Zuletzt aktualisiert: · 7 Min. Lesezeit

Kurze Antwort

Wie crawle ich eine Website mit WebReaderAPI zu Markdown?

Senden Sie die Start-URL an POST https://webreaderapi.com/api/v1/crawl mit einer Seiten-limit. WebReaderAPI liest die Website im Hintergrund, nur dieselbe Domain, folgt ihrer Sitemap, robots.txt und Crawl-delay, bis zu 10.000 Seiten pro Job. Holen Sie die Markdown-Seiten aus dem Job, jeweils eine Seite Ergebnisse. Jede gelesene Seite kostet 1 Credit (2 mit Browser), ab 0,07 $/1K Seiten Stand Oktober 2026. Ohne KYC; mit Krypto bezahlen.

Jobs auf einen Blick

BatchBis zu 100 URLs pro Batch-Job: POST https://webreaderapi.com/api/v1/batch
CrawlEine Website pro Job crawlen, bis zu 10.000 Seiten, entlang ihrer Sitemap, ihrer robots.txt und ihrer Crawl-delay: POST https://webreaderapi.com/api/v1/crawl
ErgebnisseGET https://webreaderapi.com/api/v1/jobs/{job_id}, dann ?cursor=… für die nächste Seite Ergebnisse
AbrechnungJede gelesene Seite wird wie ein /read-Aufruf abgerechnet; von robots.txt übersprungene Seiten und fehlgeschlagene Seiten kosten nichts
Umfang eines CrawlsEine Domain; Links zu anderen Domains werden aufgeführt, aber nicht gelesen
Job abbrechenIn v1 nicht verfügbar: Setzen Sie limit auf die maximale Seitenzahl, die Sie zu zahlen bereit sind

Batch-Job starten

POST/api/v1/batch

Liest bis zu 100 URLs im Hintergrund mit denselben Optionen. Die Optionen verwenden die Namen und Werte von /read. Die Antwort ist die Job-ID; Werte dienen nur als Beispiel.

Authentifizierung: API-Schlüssel im Authorization: Bearer API_KEY-Header.

Request-Body

FeldTypErforderlichBeschreibung
urlsarray of stringsJa1 bis 100 http- oder https-URLs. Duplikate werden einmal gelesen.
optionsobjectNeinJeder /read-Parameter außer url: format, main_content, render, include_links, include_images, country, max_chars, timeout.
Beispiel: three articles as Markdown
{
  "urls": [
    "https://example.com/blog/post-1",
    "https://example.com/blog/post-2",
    "https://example.org/news/launch"
  ],
  "options": {
    "format": "markdown",
    "max_chars": 50000
  }
}

Antwort 202 Accepted

{
  "job_id": "job_5c1e8a90d2"
}

Codebeispiele

curl
curl -s "https://webreaderapi.com/api/v1/batch" \
  -H "Authorization: Bearer $WEBREADER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com/blog/post-1", "https://example.com/blog/post-2"], "options": {"format": "markdown"}}'
Python
import os
import requests

resp = requests.post(
    "https://webreaderapi.com/api/v1/batch",
    headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
    json={"urls": ["https://example.com/blog/post-1", "https://example.com/blog/post-2"], "options": {"format": "markdown"}},
    timeout=30,
)
print(resp.json()["job_id"])
Node.js
const res = await fetch('https://webreaderapi.com/api/v1/batch', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ urls: ['https://example.com/blog/post-1', 'https://example.com/blog/post-2'], options: { format: 'markdown' } }),
});
console.log((await res.json()).job_id);

Crawling-Job starten

POST/api/v1/crawl

Liest eine Webseite ab einer Start-URL, breadth first. Der Crawler bleibt auf der Domain der Start-URL, nutzt die in robots.txt genannte oder unter /sitemap.xml gefundene Sitemap und beachtet robots.txt und Crawl-delay. Werte sind beispielhaft.

Authentifizierung: API-Schlüssel im Authorization: Bearer API_KEY-Header.

Request-Body

FeldTypErforderlichBeschreibung
urlstringJaDie Startseite, etwa die Homepage einer Dokumentationsseite.
limitintegerNeinMaximale Anzahl zu lesender Seiten, bis zu 10.000. Der Job endet, wenn er diese Zahl erreicht.
max_depthintegerNeinMaximale Anzahl an Link-Schritten weg von der Start-URL.
include_pathsarray of stringsNeinEinfache Pfadmuster zum Behalten, etwa /docs/*.
exclude_pathsarray of stringsNeinEinfache Pfadmuster zum Überspringen, etwa /blog/tag/*.
optionsobjectNeinJeder /read-Parameter außer url, angewendet auf jede Seite.
Beispiel: the docs section of a site, 500 pages at most
{
  "url": "https://docs.example.com/",
  "limit": 500,
  "max_depth": 3,
  "include_paths": [
    "/docs/*"
  ],
  "exclude_paths": [
    "/docs/archive/*"
  ],
  "options": {
    "format": "markdown"
  }
}

Antwort 202 Accepted

{
  "job_id": "job_8b27f41c0e"
}

Codebeispiele

curl
curl -s "https://webreaderapi.com/api/v1/crawl" \
  -H "Authorization: Bearer $WEBREADER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://docs.example.com/", "limit": 500, "include_paths": ["/docs/*"]}'
Python
import os
import requests

resp = requests.post(
    "https://webreaderapi.com/api/v1/crawl",
    headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
    json={"url": "https://docs.example.com/", "limit": 500, "include_paths": ["/docs/*"]},
    timeout=30,
)
print(resp.json()["job_id"])
Node.js
const res = await fetch('https://webreaderapi.com/api/v1/crawl', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ url: 'https://docs.example.com/', limit: 500, include_paths: ['/docs/*'] }),
});
console.log((await res.json()).job_id);

Job-Status und Ergebnisse abrufen

GET/api/v1/jobs/{job_id}

Gibt den Status des Jobs und die nächsten fertigen Ergebnisse zurück. Jedes Element von results ist entweder eine vollständige /read-Antwort oder {url, error} für eine Seite, die nicht gelesen werden konnte. Wenn next_cursor vorhanden ist, rufen Sie erneut auf, wobei cursor darauf gesetzt ist; fehlt es, sind noch keine weiteren Ergebnisse fertig. Werte sind beispielhaft.

Authentifizierung: API-Schlüssel im Authorization: Bearer API_KEY-Header.

Parameter

NameInTypErforderlichBeschreibung
job_idpathstringJaDie von /batch oder /crawl zurückgegebene ID.
cursorquerystringNeinDer next_cursor-Wert aus dem vorherigen Aufruf, um die folgenden Ergebnisse zu erhalten.

Antwort 200

{
  "job_id": "job_8b27f41c0e",
  "status": "running",
  "results": [
    {
      "url": "https://docs.example.com/docs/install",
      "final_url": "https://docs.example.com/docs/install",
      "status_code": 200,
      "rendered": false,
      "credits_used": 1,
      "title": "Install",
      "markdown": "# Install\n\nRun the installer...",
      "word_count": 418
    },
    {
      "url": "https://docs.example.com/docs/private",
      "error": {
        "code": "blocked_by_robots",
        "message": "robots.txt disallows this page for WebReaderAPI."
      }
    }
  ],
  "next_cursor": "c_000002",
  "credits_used": 1
}

Codebeispiele

curl
curl -sG "https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e" \
  -H "Authorization: Bearer $WEBREADER_API_KEY" \
  -d cursor=c_000002
Python
import os
import requests

resp = requests.get(
    "https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e",
    headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
    params={"cursor": "c_000002"},
    timeout=30,
)
job = resp.json()
print(job["status"], len(job["results"]), job.get("next_cursor"))
Node.js
const res = await fetch('https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e?cursor=c_000002', {
  headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}` },
});
const job = await res.json();
console.log(job.status, job.results.length, job.next_cursor);

Wie warte ich, bis ein Job fertig ist?

Fragen Sie /jobs/{job_id} ab und behalten Sie den Cursor. Verarbeiten Sie die erhaltenen Ergebnisse und rufen Sie dann erneut auf, wobei cursor auf next_cursor gesetzt ist. Wenn next_cursor fehlt und status done ist, haben Sie alles; wenn es fehlt und der Job noch running ist, warten Sie und fragen Sie mit demselben Cursor erneut.

Beginnen Sie mit einer Abfrage alle 2 Sekunden und verdoppeln Sie die Wartezeit bis 30 Sekunden, solange nichts Neues eintrifft. Ein Crawl, der das Crawl-delay einer Website beachtet, kann eine Weile dauern, also ist eine lange Wartezeit normal und kostet nichts.

Python: einen Job abfragen und jede Seite als .md-Datei speichern
import os
import pathlib
import re
import time

import requests

JOBS = "https://webreaderapi.com/api/v1/jobs"
HEADERS = {"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]}


def save_job(job_id, folder="pages"):
    out = pathlib.Path(folder)
    out.mkdir(exist_ok=True)
    cursor, wait, saved = None, 2, 0
    while True:
        params = {"cursor": cursor} if cursor else {}
        job = requests.get(f"{JOBS}/{job_id}", headers=HEADERS, params=params, timeout=30).json()
        for item in job["results"]:
            if "error" in item:
                print("skipped", item["url"], item["error"]["code"])
                continue
            name = re.sub(r"[^a-z0-9]+", "-", item["final_url"].lower()).strip("-")[:120]
            (out / f"{name}.md").write_text(item["markdown"], encoding="utf-8")
            saved += 1
        if job.get("next_cursor"):
            cursor, wait = job["next_cursor"], 2
            continue
        if job["status"] == "done":
            return saved
        time.sleep(wait)
        wait = min(wait * 2, 30)


if __name__ == "__main__":
    print(save_job("job_8b27f41c0e"), "pages saved")

Welche Seiten liest ein Crawl?

Ein Crawl startet bei Ihrer URL und bewegt sich Link-Schritt für Link-Schritt nach außen, breadth first, bis zu max_depth. Er liest außerdem die Sitemap der Website, aus der in robots.txt angegebenen Adresse oder aus /sitemap.xml, um Seiten zu finden, auf die nur wenige Links zeigen.

  • Nur dieselbe Domain. Links zu anderen Domains werden in den Ergebnissen aufgeführt, wenn Sie include_links anfordern, aber sie werden nicht gelesen.
  • Pfadfilter. include_paths und exclude_paths nehmen einfache Muster wie /blog/*.
  • Eine Kopie pro Seite. Wenn eine Website eine kanonische URL angibt, wird eine über mehrere Adressen erreichte Seite einmal gelesen.
  • Ein hartes Limit. Der Job endet, wenn er limit Seiten gelesen hat.

Wie beachtet ein Crawl die Website?

Jede Anfrage trägt den User-Agent WebReaderAPI/1.0 (+https://webreaderapi.com/bot/), und der Crawler folgt den robots.txt-Regeln für WebReaderAPI oder für alle Roboter, wenn keine ihn nennen. Nicht erlaubte Seiten werden übersprungen und erscheinen in results mit dem Fehler blocked_by_robots; sie kosten nichts.

Wenn robots.txt ein Crawl-delay festlegt, wartet der Crawler diese Zeit zwischen zwei Anfragen an die Website. Wenn eine Website in ihrer robots.txt Content-Signal: ai-input=no deklariert, lesen wir ihre Seiten nicht für Sie. 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.

Was kostet ein Crawl?

Jede gelesene Seite kostet, was ein /read-Aufruf kosten würde: 1 Credit, 2 wenn die Seite einen Browser benötigte, plus 10 mit country. Übersprungene und fehlgeschlagene Seiten sind kostenlos. Die credits_used des Jobs summiert, was bisher berechnet wurde.

Eine Dokumentationsseite mit 500 Seiten, ohne Browser gelesen, verbraucht etwa 500 Credits, was das 10.000 Seiten-Pack (3,75 $) um ein Vielfaches abdeckt. Da ein Job in v1 nicht abgebrochen werden kann, ist limit Ihre Ausgabengrenze: Setzen Sie es auf die maximale Anzahl Seiten, für die Sie zu zahlen bereit sind.

Batch und Crawl: häufige Fragen

Soll ich /batch oder viele /read-Aufrufe verwenden?

Verwenden Sie /batch, wenn Sie die URLs bereits haben und nicht jede Antwort sofort benötigen. Das erspart Ihnen die Verwaltung von Nebenläufigkeit und Wiederholungen. Verwenden Sie /read, wenn ein Agent jetzt eine Seite braucht.

Wie lange werden Job-Ergebnisse aufbewahrt?

Holen Sie sie ab, sobald sie fertig sind. Ergebnisse warten, bis Sie sie abrufen; nach der Zustellung wird keine Kopie des Seiteninhalts aufbewahrt, speichern Sie also selbst, was Sie brauchen.

Nein. Ein Crawl liest eine Domain. Andere Domains erscheinen als Links, wenn Sie sie anfordern, und Sie können diese URLs an /batch senden, wenn Sie sie lesen lassen möchten.

Kann ich einen gestarteten Crawl stoppen?

In v1 nicht. Der Job endet bei limit Seiten, wählen Sie also ein Limit, das zu Ihrem Budget passt. Bereits gelesene Seiten bleiben berechnet; nie gelesene Seiten kosten nichts.

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

API-Schlüssel erhalten