Anmelden

Aufbau des SDK

Das Node SDK ist ein dünner Wrapper um dieselbe HTTP-API, die in der API Reference dokumentiert ist. Jeder Crawling API-Parameter, den Sie in einem rohen HTTP-Aufruf als Query-String anhängen würden, ist im SDK als Key im Options-Objekt erreichbar - Namen, Defaults und Verhalten sind eins zu eins abgebildet. Es gibt keinen Parameter, den das SDK hinzufügt; es gibt keinen, den es versteckt.

Was Sie davon haben, es statt fetch / axios direkt zu verwenden:

  • URL-Encoding, Parameter-Validierung und Response-Parsing werden out of the box erledigt - der Code liest sich wie Produktcode, nicht wie HTTP-Plumbing.
  • Sowohl ESM (import { CrawlingAPI } from 'crawlbase') als auch CommonJS (const { CrawlingAPI } = require('crawlbase')) werden unterstützt.
  • Eine einzige Client-Klasse pro Crawlbase API, alle mit derselben Constructor- und Aufrufsignatur.
  • Sinnvolle Defaults (90-Sekunden-Timeout, automatisches JSON-Parsing von format=json-Responses, UTF-8-Decoding), die genau dem entsprechen, was die meisten Teams bei ihrer ersten Integration manuell konfigurieren.

Das SDK ist Open Source, MIT-lizenziert und nimmt Community-PRs unter github.com/crawlbase/crawlbase-node entgegen.

Installation

Aktuelle Version auf npm. Funktioniert mit Node.js 16+ über alle gängigen Package-Manager.

npm install crawlbase

# Or via pnpm / yarn / bun
pnpm add crawlbase
yarn add crawlbase
bun add crawlbase

Quellcode auf GitHub. Issues + PRs sind willkommen.

Authentifizierung

Jede Crawlbase API authentifiziert sich über dasselbe Token-Modell. Zu einem einzigen Konto gehören zwei Token-Typen:

  • Normal Token (TCP) - für statisches HTML, JSON-Endpoints und alles, was keinen Browser benötigt. Schneller und günstiger.
  • JavaScript Token - für SPAs, lazy-geladene Feeds und alles, was Inhalte hinter clientseitigem Rendering versteckt. Erforderlich, um page_wait, ajax_wait, scroll und css_click_selector zu nutzen.

Verwenden Sie in Produktion Umgebungsvariablen. Das SDK liest selbst keine env-Variablen - das ist Absicht, damit Sie die Kontrolle darüber behalten, woher die Credentials kommen - aber das idiomatische Muster lautet:

import { CrawlingAPI } from 'crawlbase';

// Pick the right token at instantiation; the SDK doesn't switch
// tokens per-call, so keep two clients if you alternate.
const api = new CrawlingAPI({ token: process.env.CRAWLBASE_TOKEN });
const js  = new CrawlingAPI({ token: process.env.CRAWLBASE_JS_TOKEN });

await api.get('https://github.com/anthropic');
await js.get('https://feed.example.com', { page_wait: 2000 });

Vollständiges Token-Modell + Dashboard-Speicherorte auf der Seite Authentication.

Quickstart

Drei Zeilen vom Import bis zum gecrawlten HTML. Sowohl ESM als auch CommonJS funktionieren:

// ESM
import { CrawlingAPI } from 'crawlbase';

const api = new CrawlingAPI({ token: 'YOUR_TOKEN' });
const res = await api.get('https://github.com/anthropic');

if (res.statusCode === 200) {
  console.log(res.body);
}

// CommonJS - same shape
// const { CrawlingAPI } = require('crawlbase');

Verzweigen Sie anhand von response.statusCode (der HTTP-Status des SDK gegenüber Crawlbase) und response.headers.pc_status (das Crawlbase-Verdikt - siehe Errors weiter unten), wenn Sie entscheiden, ob ein Retry erfolgen soll. Übergeben Sie { format: 'json' }, um statt des rohen Seiteninhalts einen JSON-Envelope zu erhalten.

Alle APIs in einem Paket

Jede Crawlbase API hat eine passende Client-Klasse. Gleicher Constructor, gleiche get- / post-Verben.

import {
  CrawlingAPI,    // general-purpose page fetch
  ScraperAPI,     // parsed JSON for supported sites
  LeadsAPI,       // domain-scoped email extraction (legacy)
  ScreenshotsAPI, // screenshots of any URL
} from 'crawlbase';

const token = { token: 'YOUR_TOKEN' };

const crawl   = new CrawlingAPI(token);
const scraper = new ScraperAPI(token);
const leads   = new LeadsAPI(token);
const shots   = new ScreenshotsAPI(token);

// Push high-volume async jobs to the Enterprise Crawler via the
// Crawling API: api.get(url, { async: true, callback: '...',
// crawler: 'YourCrawler' }). See /docs/crawler for the queue
// workflow.

Gängige Muster

JavaScript-Rendering

Für SPAs, lazy-geladene Feeds und Seiten, deren initiales HTML leer ist, instanziieren Sie den Client mit dem JavaScript token und übergeben eine beliebige Kombination aus page_wait, ajax_wait, scroll und css_click_selector. Sinnvolle Reihenfolge: zuerst ein fester Wait, dann Network-Idle, dann Scroll für Lazy-Load, dann Click für ein eventuelles Gating-UI-Element.

const api = new CrawlingAPI({ token: 'YOUR_JS_TOKEN' });
const res = await api.get('https://spa.example.com', {
  page_wait: 2000,
  ajax_wait: true,
  scroll: true,
});

Eingebauten Scraper verwenden

Sparen Sie sich auf unterstützten Seiten den Parser komplett. Übergeben Sie scraper: 'NAME', und der Response-Body wird zu einem JSON-String mit den strukturierten Feldern, die auf der jeweiligen Scraper-Seite dokumentiert sind.

import { ScraperAPI } from 'crawlbase';

const api = new ScraperAPI({ token: 'YOUR_TOKEN' });
const res = await api.get(
  'https://www.amazon.com/dp/1098145356',
  { scraper: 'amazon-product-details' }
);
const data = JSON.parse(res.body);
console.log(data.name, data.price);

Geo-Routing

Übergeben Sie country: 'ISO', um den Crawl über die Exit-Nodes des entsprechenden Landes zu leiten. Nützlich, sobald das Ziel IP-basiert lokalisierte Inhalte ausliefert.

const api = new CrawlingAPI({ token: 'YOUR_TOKEN' });

// Hit the German Amazon catalog from a German residential IP
const res = await api.get(
  'https://www.amazon.com/dp/1098145356',
  { country: 'DE' }
);

Retry mit Backoff

Empfohlene Retry-Strategie: exponentielles Backoff, gedeckelt bei 3–5 Versuchen, Retry nur bei transienten Fehlern (5xx oder leerer Body), kein Retry bei 4xx.

const api = new CrawlingAPI({ token: 'YOUR_TOKEN' });
const sleep = ms => new Promise(r => setTimeout(r, ms));

async function crawl(url, attempts = 5) {
  for (let i = 0; i < attempts; i++) {
    const res = await api.get(url);
    if (res.statusCode === 200 && Number(res.headers.pc_status) === 200) {
      return res;
    }
    if (res.statusCode >= 400 && res.statusCode < 500) {
      throw new Error(`client error ${res.statusCode}: ${url}`);
    }
    await sleep(Math.random() * (2 ** i) * 1000);
  }
  throw new Error(`Failed: ${url}`);
}

Async-Crawls + Webhooks

Fire-and-forget-Modus. Der SDK-Aufruf wird sofort mit einer rid aufgelöst; Crawlbase POSTet das Ergebnis an Ihre Callback-URL, sobald die Seite bereit ist. Nützlich für Batch-Jobs und langsame Ziele.

const api = new CrawlingAPI({ token: 'YOUR_TOKEN' });
const res = await api.get('https://example.com', {
  async: true,
  callback: 'https://your-app.com/webhook',
});
const rid = res.rid;  // correlate the eventual webhook delivery

// Your Express / Fastify / Hono webhook receives a POST with:
//   { rid, url, original_status, pc_status, body }

Für sehr hohe Volumen (Millionen von URLs) verwenden Sie den Enterprise Crawler, der vor genau dieser asynchronen Pipeline sitzt — mit Retries, Rate-Management und Ergebniszustellung.

Sticky Sessions

Manche Flows benötigen über mehrere Aufrufe hinweg dieselbe Residential-IP - ein Checkout, eine paginierte Suche, eine eingeloggte Session. Übergeben Sie cookies_session mit einem stabilen Identifier, und Crawlbase verwendet für ca. 30 Minuten denselben Exit-Node.

const api = new CrawlingAPI({ token: 'YOUR_JS_TOKEN' });

const session = `checkout-${userId}`;
await api.get('https://shop.example.com/cart',     { cookies_session: session });
await api.get('https://shop.example.com/checkout', { cookies_session: session });
await api.get('https://shop.example.com/confirm',  { cookies_session: session });

Errors & Retries

Die Crawlbase-Plattform liefert bei jeder Response zwei Statuscodes: den SDK-eigenen response.statusCode (HTTP-Status der Anfrage an Crawlbase selbst) und den pc_status Response-Header (das Crawlbase-Verdikt zum Ziel - die vollständige Liste finden Sie in der Crawling API Errors-Tabelle). Das Node SDK stellt die Response-Header als einfaches Objekt unter response.headers bereit, sodass das Verdikt als response.headers.pc_status lesbar ist. Verzweigen Sie immer darauf, wenn Sie über einen Retry entscheiden - ein Ziel kann 200 mit leerem Body zurückgeben, in welchem Fall response.statusCode zwar 200 ist, response.headers.pc_status aber 520.

const res = await api.get(url);
const pc = Number(res.headers.pc_status);

if (pc === 200) {
  use(res.body);
} else if (pc === 520 || pc === 525) {
  // 520 = empty body, 525 = anti-bot couldn't be solved.
  // Switch to JS token and retry.
  await retryWithJsToken(url);
} else if ([521, 522, 523].includes(pc)) {
  // Target unreachable or timed out. Retry with backoff.
  schedule_retry(url);
} else {
  logger.error('crawl failed', { url, pc_status: pc });
}

Alle Retries gegen die Plattform sind kostenlos - nur erfolgreiche Responses (pc_status: 200) zählen auf Ihr Kontingent. Das macht aggressives Backoff günstig; die einzigen echten Kosten eines Retries sind zusätzliche Latenz.

Performance & Best Practices

  • Verwenden Sie pro Token einen einzigen Client wieder. Der Constructor ist günstig, aber jede Instanz öffnet ihren eigenen Connection-Pool. Bauen Sie ihn einmal auf Modul-Ebene und teilen Sie ihn über alle Aufrufe.
  • Verwenden Sie das günstigste Token, das funktioniert. Greifen Sie nicht „nur zur Sicherheit" standardmäßig zum JavaScript token - Anfragen mit Normal token sind schneller und benötigen weniger Concurrency. Wechseln Sie erst dann zu JS, wenn die Normal-Response leer ist oder von Anti-Bot-Maßnahmen blockiert wird.
  • Bevorzugen Sie ajax_wait gegenüber page_wait. Feste Delays verbrennen Concurrency bei jedem Request, auch bei schnellen.
  • Für Batch-Jobs: async + Webhook oder Push an den Enterprise Crawler. Der synchrone Modus ist der richtige Default für Ad-hoc- und interaktive Nutzung; für dauerhaft hochvolumige Übermittlung wechseln Sie zu async, damit Ihr Concurrency-Slot in dem Moment frei wird, in dem ein Request in die Queue geht.
  • Beachten Sie den Response-Header remaining. Er enthält die Anzahl der noch verfügbaren Concurrency-Slots - ein gesunder Client drosselt proaktiv, bevor das Limit erreicht wird.

Methodenreferenz

Alle Client-Klassen teilen sich dieselbe Oberfläche. Der Konstruktor nimmt ein einzelnes Options-Objekt entgegen; die Verben spiegeln die zugrunde liegenden HTTP-Methoden. Jede Methode gibt ein Promise zurück.

new CrawlingAPI({ token, timeout })
constructor
Initialisieren Sie einen Client mit Ihrem Token. Optional: timeout in Millisekunden (Default 90000).
.get(url, options?)
method
Sendet einen GET. options bildet jeden Crawling API-Parameter auf seinen Wert ab.
.post(url, data, options?)
method
Sendet einen POST. data ist der Body - übergeben Sie ein Objekt für form-encoded, einen String für raw.

Form der Response (Objekt, alle Eigenschaften vorhanden, auch wenn leer):

response.statusCode
number
HTTP-Status der Anfrage des SDK an Crawlbase.
response.body
string
Seiteninhalt (oder JSON-String, wenn format=json / scraper= verwendet wurde). Standardmäßig UTF-8-dekodiert.
response.url
string
Finale URL nach Redirects auf Zielseite.
response.headers
object
Response-Header in Kleinbuchstaben. Crawlbase-spezifische Statusfelder werden hier offengelegt:
  • response.headers.pc_status - Crawlbase-Verdikt zum Ziel (darauf verzweigen für Retry-Entscheidungen).
  • response.headers.original_status - HTTP-Status, den die Ziel-Seite an Crawlbase zurückgegeben hat.
  • response.headers.rid - Request ID (wenn der Aufruf async: true oder store: true enthielt).
response.json
object | undefined
Vorab geparstes JSON, wenn der Content-Type der Response JSON ist. Wird einmal vom SDK geparst, damit Sie es nicht selbst tun müssen.