Ruby
Gem Ruby officielle pour la plateforme Crawlbase. Ruby idiomatique sur Ruby 2.7+ et JRuby - même gem, toutes les APIs, des valeurs par défaut sensées qui correspondent à ce que la plupart des applications Rails configurent à la main.
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,scrolletcss_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 == 200Branchez 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
endCrawls 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)
endTous 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.
timeout en secondes (par défaut 90).options mappe n'importe quel paramètre de la Crawling API à sa valeur. Retourne un objet response.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 :
format=json / scraper= a été utilisé).async: true ou store: true).