Se connecter

Architecture du SDK

La gem Ruby 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 la gem en tant que keyword de l'appel - les noms, valeurs par défaut et comportements correspondent un à un. La gem n'ajoute aucun paramètre ; elle n'en cache aucun.

Ce que vous y gagnez par rapport à utiliser Net::HTTP / Faraday directement :

  • Encodage URL, validation des paramètres et parsing des réponses gérés d'office - le code applicatif reste concentré sur la logique métier.
  • Surface Ruby idiomatique - keyword args, noms de paramètres en snake_case, levée d'exceptions pour les échecs de transport, objets de réponse Ruby classiques.
  • Une seule classe client par API Crawlbase, toutes partageant le même constructeur et la même forme d'appel.
  • Valeurs par défaut sensées (timeout de 90 secondes, parsing JSON automatique des réponses format=json, corps encodés en UTF-8) qui correspondent à ce que la plupart des équipes configurent à la main lors de leur première intégration.

Code source sur github.com/crawlbase/crawlbase-ruby. Issues et PRs bienvenues.

Installation

Dernière version sur RubyGems. Testée sur Ruby 2.7, 3.0, 3.1, 3.2, 3.3 + JRuby.

gem install crawlbase

# Or in your Gemfile
gem 'crawlbase'

Authentification

Toutes les APIs Crawlbase s'authentifient avec le même modèle de token. Deux types de tokens cohabitent sur un même compte :

  • Normal Token (TCP) - pour le HTML statique, les endpoints JSON, tout ce qui ne nécessite pas de navigateur. Plus rapide + moins cher.
  • JavaScript Token - pour les SPAs, les flux chargés en lazy-loading, tout ce qui cache du contenu derrière un rendu côté client. Requis pour utiliser page_wait, ajax_wait, scroll et css_click_selector.

Utilisez les credentials Rails (Rails.application.credentials.crawlbase_token) ou des variables d'environnement en production. La gem ne lit ni l'un ni l'autre elle-même - c'est délibéré pour que vous gardiez le contrôle sur la provenance des credentials. Pattern :

require 'crawlbase'

# Pick the right token at instantiation; the gem doesn't switch
# tokens per-call, so keep two clients if you alternate.
api = Crawlbase::API.new(token: ENV.fetch('CRAWLBASE_TOKEN'))
js = Crawlbase::API.new(token: ENV.fetch('CRAWLBASE_JS_TOKEN'))

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

Modèle de token complet et emplacements dans le dashboard sur la page Authentication.

Démarrage rapide

Trois lignes entre le require et le HTML crawlé :

require 'crawlbase'

api = Crawlbase::API.new(token: 'YOUR_TOKEN')
res = api.get('https://github.com/anthropic')

puts res.body if res.status_code == 200

Branchez sur .status_code (le statut HTTP de la gem vers Crawlbase) et .pc_status (le verdict Crawlbase - voir Erreurs ci-dessous) lorsque vous décidez de retenter ou non. Passez format: 'json' pour recevoir une enveloppe JSON au lieu du contenu brut de la page.

Toutes les APIs dans une seule gem

Chaque API Crawlbase dispose d'une classe correspondante. Même constructeur, mêmes verbes get / post.

require 'crawlbase'

token = { token: 'YOUR_TOKEN' }

crawl = Crawlbase::API.new(**token) # general-purpose page fetch
scraper = Crawlbase::ScraperAPI.new(**token) # parsed JSON for supported sites
leads = Crawlbase::LeadsAPI.new(**token) # domain-scoped email extraction (legacy)
shots = Crawlbase::ScreenshotsAPI.new(**token) # screenshots of any URL
storage = Crawlbase::StorageAPI.new(**token) # Cloud Storage CRUD

# 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 différé et les pages dont 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 : un délai fixe, puis l'attente du network-idle, puis le scroll pour le lazy-load, puis le clic pour tout élément d'UI bloquant.

api = Crawlbase::API.new(token: 'YOUR_JS_TOKEN')
res = api.get('https://spa.example.com',
 page_wait: 2000,
 ajax_wait: true,
 scroll: true)

Utiliser un scraper intégré

Court-circuitez complètement le parser sur les sites pris en charge. Passez scraper: 'NAME' et le corps de la réponse devient une chaîne JSON contenant les champs structurés documentés sur la page de chaque scraper.

require 'crawlbase'
require 'json'

api = Crawlbase::ScraperAPI.new(token: 'YOUR_TOKEN')
res = api.get('https://www.amazon.com/dp/1098145356',
 scraper: 'amazon-product-details')
data = JSON.parse(res.body)
puts data['name'], data['price']

Routage géographique

Passez country: 'ISO' pour router le crawl à travers les nœuds de sortie de ce pays. À utiliser dès que la cible sert du contenu localisé selon l'IP.

api = Crawlbase::API.new(token: 'YOUR_TOKEN')

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

Retry avec backoff

Forme de retry recommandée : backoff exponentiel plafonné à 3-5 tentatives, retry uniquement sur les erreurs transitoires (5xx ou corps vide), pas de retry sur les 4xx.

require 'crawlbase'

api = Crawlbase::API.new(token: 'YOUR_TOKEN')

def crawl(api, url, attempts: 5)
 attempts.times do |i|
 res = api.get(url)
 return res if res.status_code == 200 && res.pc_status.to_i == 200
 raise "client error: %d" % res.status_code if (400..499).include?(res.status_code)
 sleep(rand * (2**i)) # exponential backoff with jitter
 end
 raise "Failed: %s" % url
end

Crawls async et webhooks

Mode fire-and-forget. L'appel à la gem retourne immédiatement avec un rid ; Crawlbase POSTe le résultat vers votre URL de callback dès que la page est prête. Utile pour les jobs batch et les cibles lentes.

api = Crawlbase::API.new(token: 'YOUR_TOKEN')
res = api.get('https://example.com',
 async: true,
 callback: 'https://your-app.com/webhook')
rid = res.rid # correlate the eventual webhook delivery

# Your Rails / Sinatra webhook receives a POST with:
# { rid, url, original_status, pc_status, body }

Pour les très gros volumes (millions d'URLs), utilisez le Enterprise Crawler, qui se place devant ce même pipeline async.

Sessions persistantes

Certains flows nécessitent la même IP résidentielle sur plusieurs appels. Passez cookies_session avec un identifiant stable et Crawlbase réutilise le même nœud de sortie pendant ~30 minutes.

api = Crawlbase::API.new(token: 'YOUR_JS_TOKEN')

session = "checkout-#{user_id}"
api.get('https://shop.example.com/cart', cookies_session: session)
api.get('https://shop.example.com/checkout', cookies_session: session)
api.get('https://shop.example.com/confirm', cookies_session: session)

Erreurs & retries

La plateforme expose deux codes de statut sur chaque réponse : le .status_code propre à la gem (statut HTTP de la requête vers Crawlbase lui-même) et .pc_status (verdict de Crawlbase sur la cible - voir le tableau des erreurs de la Crawling API pour la liste complète). Branchez toujours sur .pc_status lorsque vous décidez de retenter - une cible peut renvoyer 200 avec un corps vide, auquel cas .status_code vaut 200 mais .pc_status vaut 520.

res = api.get(url)
pc = res.pc_status.to_i

case pc
when 200
 use(res.body)
when 520, 525
 # 520 = empty body, 525 = anti-bot couldn't be solved.
 # Switch to JS token and retry.
 retry_with_js_token(url)
when 521, 522, 523
 # Target unreachable or timed out. Retry with backoff.
 schedule_retry(url)
else
 Rails.logger.error('crawl failed', url: url, pc_status: pc)
end

Tous les retries contre la plateforme sont gratuits - seules les réponses réussies (pc_status: 200) sont décomptées de votre quota.

Performance & bonnes pratiques

  • Réutilisez un seul client par token. Le constructeur est peu coûteux mais chaque instance ouvre sa propre connexion. Construisez-le une seule fois au boot de l'application (un initializer Rails est l'endroit naturel), partagez-le entre les requêtes.
  • Utilisez le token le moins cher qui fonctionne. Ne basculez pas par défaut sur le JavaScript token « au cas où » - les requêtes Normal token sont plus rapides et consomment moins de concurrence. Passez en JS uniquement lorsque la réponse Normal est vide ou bloquée par anti-bot.
  • Préférez ajax_wait à page_wait. Les délais fixes brûlent de la concurrence sur chaque requête, même les rapides.
  • Pour les jobs batch : async + webhook, ou bascule vers l'Enterprise Crawler. Des workers Sidekiq qui appellent la gem de façon synchrone vont saturer votre plafond de concurrence ; async + webhook libère le slot dès qu'une requête est mise en file.
  • Surveillez le header de réponse remaining. Il indique le nombre de slots de concurrence qu'il vous reste - levez le pied de manière proactive avant d'atteindre la limite plutôt que de réagir aux 429.

Référence des méthodes

Toutes les classes client partagent la même surface. Le constructeur prend des keyword arguments ; les verbes reflètent les méthodes HTTP sous-jacentes.

Crawlbase::API.new(token:, timeout:)
constructeur
Initialise un client avec votre token. Optionnel : timeout en secondes (par défaut 90).
#get(url, **options)
méthode
Envoie un GET. options mappe n'importe quel paramètre de la Crawling API à sa valeur. Retourne un objet response.
#post(url, data, **options)
méthode
Envoie un POST. data est le body - passez un hash pour du form-encoded, une string pour du brut.

Forme de la réponse - méthodes sur l'objet response :

.status_code
Integer
Statut HTTP de la requête de la gem vers Crawlbase.
.pc_status
Integer
Verdict de Crawlbase sur la cible. Branchez dessus pour les décisions de retry.
.original_status
Integer
Statut HTTP que la cible a retourné à Crawlbase.
.url
String
URL finale après les redirections côté cible.
.body
String
Contenu de la page (ou string JSON lorsque format=json / scraper= a été utilisé).
.headers
Hash
En-têtes de réponse du site cible.
.rid
String
ID de la requête (lorsque async: true ou store: true).