Ruby
Offizielles Ruby-Gem für die Crawlbase-Plattform. Idiomatisches Ruby über Ruby 2.7+ und JRuby hinweg: dasselbe Gem, jede API, sinnvolle Defaults, die dem entsprechen, was die meisten Rails-Apps von Hand konfigurieren.
Aufbau des SDKs
Das Ruby-Gem 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 Gem als Keyword am Aufruf erreichbar: Namen, Defaults und Verhalten werden eins zu eins abgebildet. Es gibt keinen Parameter, den das Gem hinzufügt, und keinen, den es versteckt.
Was Sie davon haben, statt direkt Net::HTTP / Faraday zu nutzen:
- URL-Encoding, Parameter-Validierung und Response-Parsing direkt out of the box: Der Anwendungscode bleibt auf die Business-Logik fokussiert.
- Idiomatische Ruby-Oberfläche: Keyword-Args, snake_case-Parameternamen, Exception-Werfen bei Transport-Fehlern, schlichte Plain-Old-Ruby-Response-Objekte.
- Eine einzige Client-Klasse pro Crawlbase-API, alle mit derselben Konstruktor- / Aufruf-Form.
- Sinnvolle Defaults (90-Sekunden-Timeout, automatisches JSON-Parsing von
format=json-Responses, UTF-8-kodierte Bodies), die dem entsprechen, was die meisten Teams bei ihrer ersten Integration von Hand konfigurieren.
Quellcode auf github.com/crawlbase/crawlbase-ruby. Issues + PRs willkommen.
Installation
Aktuelle Version auf RubyGems. Getestet mit Ruby 2.7, 3.0, 3.1, 3.2, 3.3 + JRuby.
gem install crawlbase
# Or in your Gemfile
gem 'crawlbase'Authentifizierung
Jede Crawlbase-API authentifiziert sich über dasselbe Token-Modell. Pro Account gibt es zwei Token-Typen:
- Normal Token (TCP) - für statisches HTML, JSON-Endpoints, alles, was keinen Browser benötigt. Schneller + günstiger.
- JavaScript Token
- für SPAs, lazy-geladene Feeds, alles, was Inhalte hinter Client-seitigem Rendering versteckt. Erforderlich für die Nutzung von
page_wait,ajax_wait,scrollundcss_click_selector.
Verwenden Sie in Produktion Rails Credentials (Rails.application.credentials.crawlbase_token) oder Umgebungsvariablen. Das Gem liest weder das eine noch das andere selbst: Das ist bewusst so, damit Sie die Kontrolle darüber behalten, woher die Credentials kommen. 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)Vollständiges Token-Modell + Dashboard-Pfade auf der Seite Authentication.
Quickstart
Drei Zeilen vom require bis zum gecrawlten HTML:
require 'crawlbase'
api = Crawlbase::API.new(token: 'YOUR_TOKEN')
res = api.get('https://github.com/anthropic')
puts res.body if res.status_code == 200Verzweigen Sie auf .status_code (der HTTP-Status des Gems an Crawlbase) und .pc_status (das Crawlbase-Verdict, siehe Errors unten), wenn Sie entscheiden, ob ein Retry erfolgen soll. Übergeben Sie format: 'json', um einen JSON-Envelope statt rohen Seiteninhalt zu erhalten.
Alle APIs in einem Gem
Jede Crawlbase-API hat eine entsprechende Klasse. Gleicher Konstruktor, gleiche get / post-Verben.
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.Gängige Muster
JavaScript-Rendering
Für SPAs, lazy-loaded Feeds und Seiten, deren initiales HTML leer ist, instanziieren Sie mit dem JavaScript token und übergeben eine beliebige Kombination aus page_wait, ajax_wait, scroll und css_click_selector. Sinnvolle Reihenfolge: ein fester Wait, dann Network-Idle, dann Scroll für Lazy-Load, dann Click für etwaige UI-Elemente, die als Gate dienen.
api = Crawlbase::API.new(token: 'YOUR_JS_TOKEN')
res = api.get('https://spa.example.com',
page_wait: 2000,
ajax_wait: true,
scroll: true)Eingebauten Scraper nutzen
Auf unterstützten Seiten den Parser komplett überspringen. Ü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.
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']Geo-Routing
Übergeben Sie country: 'ISO', um den Crawl über die Exit-Nodes des jeweiligen Landes zu leiten. Nutzen Sie das immer, wenn das Ziel IP-basierten lokalisierten Content ausliefert.
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 mit Backoff
Empfohlene Retry-Form: exponentielles Backoff, gedeckelt auf 3-5 Versuche, Retry nur bei transienten Fehlern (5xx oder leerer Body), kein Retry bei 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
endAsync-Crawls + Webhooks
Fire-and-forget-Modus. Der Gem-Aufruf kehrt sofort mit einer rid zurück; Crawlbase POSTet das Ergebnis an Ihre Callback-URL, sobald die Seite bereit ist. Nützlich für Batch-Jobs und langsame Ziele.
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 }Für sehr hohe Volumina (Millionen von URLs) verwenden Sie den Enterprise Crawler, der vor genau dieser async-Pipeline sitzt.
Sticky Sessions
Manche Flows brauchen über mehrere Calls hinweg dieselbe Residential-IP. Übergeben Sie cookies_session mit einem stabilen Identifier, und Crawlbase verwendet rund 30 Minuten lang denselben Exit-Node weiter.
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)Errors & Retries
Die Plattform liefert in jeder Response zwei Status-Codes: den eigenen .status_code des Gems (HTTP-Status der Anfrage an Crawlbase selbst) und .pc_status (Crawlbases Verdict zum Ziel, siehe die Crawling API-Errors-Tabelle für die vollständige Liste). Verzweigen Sie immer auf .pc_status, wenn Sie entscheiden, ob ein Retry erfolgen soll: Ein Ziel kann 200 mit leerem Body zurückgeben - in diesem Fall ist .status_code gleich 200, aber .pc_status ist 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)
endAlle Retries gegen die Plattform sind kostenlos: Nur erfolgreiche Responses (pc_status: 200) zählen auf Ihr Kontingent.
Performance & Best Practices
- Pro Token einen einzigen Client wiederverwenden. Der Konstruktor ist günstig, aber jede Instanz öffnet eine eigene Connection. Bauen Sie ihn einmal beim App-Boot (ein Rails-Initializer ist der natürliche Ort) und teilen Sie ihn über alle Requests.
- Verwenden Sie das günstigste Token, das funktioniert. Verwenden Sie nicht standardmäßig den JavaScript token «nur zur Sicherheit»: Normal-token-Requests sind schneller und nutzen weniger Concurrency. Wechseln Sie nur dann zu JS, wenn die Normal-Response leer oder durch Anti-Bot blockiert ist.
- Bevorzugen Sie
ajax_waitgegenüberpage_wait. Feste Delays verbrennen Concurrency bei jedem Request, auch bei den schnellen. - Für Batch-Jobs: async + Webhook oder Push an den Enterprise Crawler. Sidekiq-Worker, die das Gem synchron aufrufen, sättigen Ihr Concurrency-Limit; async + Webhook gibt den Slot frei, sobald ein Request in die Queue gestellt ist.
- Beobachten Sie den
remaining-Response-Header. Er enthält die Anzahl der Concurrency-Slots, die Ihnen noch übrig bleiben - drosseln Sie proaktiv, bevor Sie das Limit erreichen, statt auf 429er zu reagieren.
Methodenreferenz
Alle Client-Klassen teilen sich dieselbe Oberfläche. Der Konstruktor nimmt Keyword-Argumente entgegen; die Verben spiegeln die zugrundeliegenden HTTP-Methoden.
timeout in Sekunden (Default 90).options mappt jeden Crawling API-Parameter auf seinen Wert. Gibt ein Response-Objekt zurück.data ist der Body: Übergeben Sie ein Hash für form-encoded, einen String für raw.Response-Form: Methoden am Response-Objekt:
format=json / scraper= verwendet wurde).async: true oder store: true).