Node.js
Client Node.js officiel pour la plateforme Crawlbase. Un seul package, toutes les APIs, async/await complet avec rejet de Promise approprié sur les erreurs de transport et objets de réponse structurés en cas de succès.
Architecture du SDK
Le SDK Node est un wrapper léger autour de la même API HTTP documentée dans la Référence API. Chaque paramètre de la Crawling API que vous ajouteriez en query string dans un appel HTTP brut est accessible depuis le SDK comme clé dans l'objet d'options : noms, valeurs par défaut et comportement correspondent un à un. Il n'y a aucun paramètre que le SDK ajoute ; il n'y a aucun paramètre qu'il masque.
Ce que vous gagnez en l'utilisant plutôt que fetch / axios directement :
- Encodage URL, validation des paramètres et parsing des réponses gérés d'emblée : le code se lit comme du code produit, pas comme de la plomberie HTTP.
- Support à la fois ESM (
import { CrawlingAPI } from 'crawlbase') et CommonJS (const { CrawlingAPI } = require('crawlbase')). - Une seule classe client par API Crawlbase, partageant toutes le même constructeur et la même forme d'appel.
- Des valeurs par défaut pertinentes (timeout de 90 secondes, parsing JSON automatique des réponses
format=json, décodage UTF-8) qui correspondent à ce que la plupart des équipes configurent à la main lors de leur première intégration.
Le SDK est open source, sous licence MIT, et accepte les PRs de la communauté sur github.com/crawlbase/crawlbase-node.
Installation
Dernière version sur npm. Compatible avec Node.js 16+ sur tous les principaux gestionnaires de packages.
npm install crawlbase
# Or via pnpm / yarn / bun
pnpm add crawlbase
yarn add crawlbase
bun add crawlbaseSource sur GitHub. Issues et PRs bienvenues.
Authentification
Chaque API Crawlbase s'authentifie avec le même modèle de token. Deux types de tokens cohabitent sur un seul compte :
- Normal Token (TCP) - pour le HTML statique, les endpoints JSON, tout ce qui ne nécessite pas de navigateur. Plus rapide et moins coûteux.
- JavaScript Token
- pour les SPAs, les flux chargés en lazy, tout ce qui cache du contenu derrière un rendu côté client. Nécessaire pour utiliser
page_wait,ajax_wait,scrolletcss_click_selector.
Utilisez des variables d'environnement en production. Le SDK ne lit pas les variables d'environnement lui-même : c'est délibéré, pour que vous gardiez le contrôle sur la provenance des identifiants. Le pattern idiomatique est :
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 });Modèle complet des tokens et emplacements dans le dashboard sur la page Authentication.
Démarrage rapide
Trois lignes entre l'import et le HTML crawlé. ESM et CommonJS fonctionnent tous deux :
// 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');Branchez sur response.statusCode (le statut HTTP du SDK vers Crawlbase) et response.headers.pc_status (le verdict Crawlbase : voir Erreurs ci-dessous) pour décider s'il faut réessayer. Passez { format: 'json' } pour recevoir une enveloppe JSON au lieu du contenu brut de la page.
Toutes les APIs dans un seul package
Chaque API Crawlbase dispose d'une classe client correspondante. Même constructeur, mêmes verbes get / post.
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.Patterns courants
Rendu JavaScript
Pour les SPAs, les flux à chargement paresseux et les pages où le HTML initial est vide, instanciez avec le JavaScript token et passez n'importe quelle combinaison de page_wait, ajax_wait, scroll et css_click_selector. Ordre à garder en tête : une attente fixe, puis network-idle, puis scroll pour le lazy-load, puis click pour tout élément d'UI bloquant.
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,
});Utiliser un scraper intégré
Sautez complètement le parser sur les sites supportés. Passez scraper: 'NAME' et le body de la réponse devient une chaîne JSON avec les champs structurés documentés sur la page de chaque scraper.
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);Routage géographique
Passez country: 'ISO' pour router le crawl à travers les nœuds de sortie de ce pays. Utilisez-le dès que la cible sert du contenu localisé en fonction de l'IP.
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 avec backoff
La forme de retry recommandée : backoff exponentiel plafonné à 3-5 tentatives, retry uniquement sur les erreurs transitoires (5xx ou body vide), pas de retry sur les 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}`);
}Crawls async + webhooks
Mode fire-and-forget. L'appel SDK se résout immédiatement avec un rid ; Crawlbase POST le résultat à votre URL de callback dès que la page est prête. Utile pour les jobs en lot et les cibles lentes.
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 }Pour de très grands volumes (millions d'URLs), utilisez l'Enterprise Crawler qui se place devant ce même pipeline async avec retries, gestion du débit et livraison des résultats.
Sessions persistantes
Certains flux nécessitent la même IP résidentielle à travers plusieurs appels : un checkout, une recherche paginée, une session authentifiée. Passez cookies_session avec un identifiant stable et Crawlbase réutilisera le même nœud de sortie pendant environ 30 minutes.
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 });Erreurs & retries
La plateforme Crawlbase expose deux codes de statut sur chaque réponse : le response.statusCode propre au SDK (statut HTTP de la requête vers Crawlbase elle-même) et l'en-tête de réponse pc_status (le verdict de Crawlbase sur la cible : voir le tableau des erreurs de la Crawling API pour la liste complète). Le SDK Node expose les en-têtes de réponse sous forme d'objet simple sur response.headers, ce qui permet de lire le verdict via response.headers.pc_status. Branchez toujours là-dessus pour décider de réessayer : une cible peut retourner 200 avec un body vide, auquel cas response.statusCode vaut 200 mais response.headers.pc_status vaut 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 });
}Tous les retries contre la plateforme sont gratuits : seules les réponses réussies (pc_status: 200) sont décomptées de votre quota. Cela rend un backoff agressif peu coûteux ; le seul vrai coût du retry est la latence supplémentaire.
Performance & bonnes pratiques
- Réutilisez un seul client par token. Le constructeur est peu coûteux mais chaque instance ouvre son propre pool de connexions sous-jacent. Construisez-le une fois au niveau du module et partagez-le entre les appels.
- Utilisez le token le moins coûteux qui fonctionne. Ne basculez pas par défaut sur le JavaScript token « au cas où » : les requêtes avec le Normal token sont plus rapides et utilisent moins de concurrence. Passez au JS uniquement lorsque la réponse Normal est vide ou bloquée par un anti-bot.
- Préférez
ajax_waitàpage_wait. Les délais fixes consomment de la concurrence sur chaque requête, même les rapides. - Pour les jobs en lot : async + webhook, ou push vers l'Enterprise Crawler. Le mode synchrone est le bon défaut pour les usages ad hoc et interactifs ; pour une soumission soutenue à fort volume, passez en async afin que votre slot de concurrence se libère dès qu'une requête est mise en file.
- Surveillez l'en-tête de réponse
remaining. Il contient le nombre de slots de concurrence qu'il vous reste : un client en bonne santé ralentit de manière proactive avant d'atteindre la limite.
Référence des méthodes
Toutes les classes client partagent la même surface. Le constructeur prend un seul objet d'options ; les verbes reflètent les méthodes HTTP sous-jacentes. Chaque méthode renvoie une Promise.
timeout en millisecondes (par défaut 90000).options associe chaque paramètre de la Crawling API à sa valeur.data est le body : passez un objet pour un encodage form, une chaîne pour du brut.Forme de la réponse (objet, toutes les propriétés présentes même lorsqu'elles sont vides) :
format=json / scraper= a été utilisé). Décodé en UTF-8 par défaut.response.headers.pc_status- verdict Crawlbase sur la cible (branchez là-dessus pour les décisions de retry).response.headers.original_status- statut HTTP que le site cible a retourné à Crawlbase.response.headers.rid- ID de requête (lorsque l'appel a été effectué avecasync: trueoustore: true).