Enterprise Crawler
Отправляйте URL в управляемую очередь, позвольте Crawlbase обрабатывать их с высокой параллельностью, получайте результаты на ваш webhook или сохранённые в Cloud Storage для последующей выгрузки. Никакого клиентского планирования, никакой логики повторов, никаких расчётов параллельности.
Crawler - это управляемая очередь, в которую вы отправляете URL и из которой получаете результаты. Три шага жизненного цикла - Setup (настройка очереди), Push (постановка URL в очередь), Pull (получение результатов) - описаны ниже по порядку.
Setup
Создайте именованную очередь в вашей консоли. Каждый crawler вмещает до 100K URL. Создавайте по одной очереди на каждую задачу - они не разделяют состояние. При создании вы выбираете:
- Уникальное имя (выбираете вы:
product-monitor,news-feedи т. д.) - Режим доставки: либо callback URL (Crawlbase отправляет POST с каждым результатом на этот webhook), либо Cloud Storage (результаты сохраняются автоматически, и вы получаете их через Storage API по собственному расписанию). Выбирается один раз при создании; два режима взаимоисключающие - один и тот же crawler не делает и то, и другое.
- Тип токена (Normal или JavaScript)
- Лимит параллельности (по умолчанию 20, можно повысить по запросу)
Доставка в Storage - это свойство crawler-а, а не push-запроса. Если crawler был создан в режиме Storage, каждый результат автоматически попадает в Cloud Storage - вам не нужно устанавливать store=true при каждом push, и crawler-ы в режиме webhook не могут переключиться на Storage для отдельного запроса.
Push
Отправляйте URL в очередь crawler-а. Push сразу возвращает rid, чтобы ваш клиент мог продолжить работу; сам обход выполняется в фоне с настроенной для crawler-а параллельностью. Передайте callback=true, чтобы запрос ушёл в очередь вместо inline-выполнения.
curl 'https://api.crawlbase.com/?token=YOUR_TOKEN&crawler=product-monitor&callback=true&url=https%3A%2F%2Fexample.com%2Fp%2F12345'import json
from crawlbase import CrawlingAPI
api = CrawlingAPI({'token': 'YOUR_TOKEN'})
res = api.get(
'https://example.com/p/12345',
{'crawler': 'product-monitor', 'callback': 'true'}
)
print(json.loads(res['body'])['rid'])const { CrawlingAPI } = require('crawlbase');
const api = new CrawlingAPI({ token: 'YOUR_TOKEN' });
const res = await api.get(
'https://example.com/p/12345',
{ crawler: 'product-monitor', callback: 'true' }
);
console.log(JSON.parse(res.body).rid);Ответ на push небольшой - это просто подтверждение того, что URL поставлен в очередь.
{ "rid": "a1B2c3D4e5F6" }Скорость push по умолчанию ограничена 30 URL/сек на токен. Каждый crawler вмещает до 100K URL в очереди ожидания, а суммарный объём по всем вашим crawler-ам ограничен 1 000 000; как только вы превысите этот лимит, push-запросы приостанавливаются, и вы получаете email - очистите очередь (или используйте purge), и push-запросы возобновятся автоматически.
Pull
Как завершённые обходы доходят до вас. Два канала, выбираемые один раз при создании crawler-а:
Webhook
Если crawler был создан с callback URL, Crawlbase отправляет POST с каждым результатом на этот webhook в момент завершения обхода. Тело - в теле запроса, метаданные - в заголовках запроса. Никакого опроса, никакого состояния на стороне клиента.
# POST https://your-app.com/webhook
# Content-Type: text/html (or application/json if scraper used)
# cb_status: 200
# original_status: 200
# rid: a1B2c3D4e5F6
# url: https://example.com/p/12345
<!DOCTYPE html><html>…</html>Ваш webhook должен:
- Быть публично доступным с серверов Crawlbase.
- Принимать
POSTи отвечать200,201или204в течение 200 мс. - Будьте идемпотентны по
rid: дубликаты доставки возможны при повторных попытках. - Подтверждайте получение до обработки - запускайте работу async, если она занимает больше времени, чем окно ответа.
Форма тела зависит от параметра format, который вы установили при push:
format=html | format=json |
|---|---|
Content-Type: text/plain | Content-Type: gzip/json |
| Тело содержит HTML страницы | Тело содержит JSON: { cb_status, original_status, rid, url, body } |
Заголовки несут метаданные: Original-Status, CB-Status, rid, url | Заголовки несут те же метаданные, поля также присутствуют в теле |
Оба формата приходят сжатыми gzip (Content-Encoding: gzip) - ваш обработчик должен распаковать данные перед разбором. Исключение - webhook-и Zapier, которые не умеют читать gzip-сжатые тела; Crawlbase определяет callback URL Zapier и пропускает сжатие.
Каждая повторная попытка считается успешным обходом для целей биллинга - Crawlbase уже оплатил стоимость прокси / браузера. Поддерживайте надёжность вашего webhook; самый дешёвый способ сократить расход кредитов - перестать терять доставки, а не бороться с политикой повторов.
Тестирование. Когда вы впервые настраиваете обработчик и хотите изучить точную структуру payload для реального URL, создайте crawler в режиме Storage параллельно с webhook-вариантом и отправляйте одни и те же URL в оба. Получайте данные из Cloud Storage по RID, и у вас будет зафиксированный эталон для сравнения с тем, что приходит на webhook - это полезно для отлова ошибок распаковки и обработки метаданных до того, как они попадут в продакшен-трафик.
Мониторинг доступности
Мониторинг-бот. Crawlbase периодически опрашивает ваш webhook, чтобы детектировать сбои. Если бот не может достучаться до вашего endpoint или вы перестали возвращать 2xx, crawler сам приостанавливается автоматически и возобновляет работу, как только endpoint снова отвечает. Проба приходит как обычный POST с JSON-телом, отличимый по User-Agent:
POST https://your-app.com/webhook
User-Agent: Crawlbase Monitoring Bot 1.0
Content-Type: application/json
{ "monitor": true }Воспринимайте такие запросы как no-op и возвращайте 200. Не обрабатывайте их как результаты обхода - реального RID, по которому можно действовать, нет.
Защита endpoint-а
Защита endpoint-а. Путь со случайной строкой (yourdomain.com/2340JOiow43djoqe21rjosi) на практике уже даёт большую часть защиты - такой URL вряд ли будет обнаружен. Для подстраховки добавьте один или несколько следующих способов:
- Токен в query-string:
?token=…, который webhook проверяет перед приёмом тела. - Кастомный заголовок, отправляемый через
callback_headersпри push (например,X-Webhook-Token|s3kret) и проверяемый на стороне сервера. - Отклоняйте всё, что не
POST. - Отклоняйте всё, где отсутствуют ожидаемые заголовки метаданных (
CB-Status,Original-Status,rid).
Мы не рекомендуем использовать allowlist по IP - Crawlbase отправляет запросы со множества IP-адресов, и их набор меняется без предупреждения.
Cloud Storage
Если crawler был создан с режимом доставки Storage, каждый результат автоматически сохраняется в Cloud Storage - никакого флага на push, никакого webhook. Ваш потребитель получает результаты по собственному расписанию через Storage API. Используйте этот режим, когда обработка ниже по конвейеру идёт пакетно, когда вы не можете запустить HTTPS endpoint или когда вам нужен стабильный URL для каждой обойдённой страницы.
Отправляйте push так же, как и для crawler-а в режиме webhook - единственное отличие в том, куда попадает результат. Как только обход URL завершится, получите данные по RID:
# Single fetch by RID
curl 'https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=a1B2c3D4e5F6'
# Or batch-drain up to 100 RIDs at once with auto_delete=true
# so storage stays small.
curl -X POST 'https://api.crawlbase.com/storage/bulk?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ "rids": ["RID1","RID2","RID3"], "auto_delete": true }'import requests
# Single fetch by RID
res = requests.get('https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=a1B2c3D4e5F6')
print(res.text)
# Or batch-drain up to 100 RIDs at once with auto_delete=true
# so storage stays small.
res = requests.post(
'https://api.crawlbase.com/storage/bulk?token=YOUR_TOKEN',
json={'rids': ['RID1', 'RID2', 'RID3'], 'auto_delete': True},
)
print(res.json())// Single fetch by RID
const one = await fetch('https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=a1B2c3D4e5F6');
console.log(await one.text());
// Or batch-drain up to 100 RIDs at once with auto_delete=true
// so storage stays small.
const bulk = await fetch('https://api.crawlbase.com/storage/bulk?token=YOUR_TOKEN', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ rids: ['RID1', 'RID2', 'RID3'], auto_delete: true }),
});
console.log(await bulk.json());require 'json'
require 'net/http'
# Single fetch by RID
puts Net::HTTP.get(URI('https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=a1B2c3D4e5F6'))
# Or batch-drain up to 100 RIDs at once with auto_delete=true
# so storage stays small.
res = Net::HTTP.post(URI('https://api.crawlbase.com/storage/bulk?token=YOUR_TOKEN'),
{ rids: %w[RID1 RID2 RID3], auto_delete: true }.to_json,
'Content-Type' => 'application/json')
puts res.bodyЧтобы узнать, когда результат готов, либо опрашивайте Find Job по конкретному RID, либо следите за Stats по счётчикам queued / completed, либо просто пакетно вычитывайте /storage/bulk по расписанию и пусть «RID not found» подсказывает, что ещё в обработке.
Эти два режима взаимоисключающие и привязываются к crawler-у при создании. Crawler в режиме webhook не пишет в Storage; crawler в режиме Storage не отправляет webhook. Чтобы переключиться, создайте новый crawler с другим режимом и перенесите push-трафик на него.
Management API
Создавайте, просматривайте, обновляйте и контролируйте ваши crawler-ы через REST. Все endpoint-ы находятся по адресу /crawler/<TOKEN>/... и аутентифицируются по токену в пути (токен в query-string не требуется).
В отличие от Crawling API, эти endpoints ожидают token в пути URL. Для crawler-ов с JavaScript-токеном замените Normal token на ваш JS-токен в каждом примере ниже.
Создание crawler-а
Создайте именованную очередь обхода. callback_url необязателен: если его не указывать, результаты по умолчанию доставляются в Cloud Storage, либо укажите собственный webhook URL, чтобы получать результаты через POST.
curl -X POST 'https://api.crawlbase.com/crawler/YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"product-monitor"}'import requests
res = requests.post(
'https://api.crawlbase.com/crawler/YOUR_TOKEN',
json={'name': 'product-monitor'},
)
print(res.json())const res = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'product-monitor' }),
});
console.log(await res.json());require 'json'
require 'net/http'
res = Net::HTTP.post(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN'),
{ name: 'product-monitor' }.to_json,
'Content-Type' => 'application/json')
puts res.bodyПолучение данных crawler-а
Получите текущую конфигурацию, статус (работает / приостановлен) и недавнюю активность crawler-а.
curl 'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor'import requests
res = requests.get('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor')
print(res.json())const res = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor');
console.log(await res.json());require 'net/http'
puts Net::HTTP.get(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor'))Обновление crawler-а
Измените callback URL или другие настройки crawler-а без его перезапуска.
curl -X PUT 'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor' \
-H 'Content-Type: application/json' \
-d '{"callback_url":"https://my-server.com/hook"}'import requests
res = requests.put(
'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor',
json={'callback_url': 'https://my-server.com/hook'},
)
print(res.json())const res = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ callback_url: 'https://my-server.com/hook' }),
});
console.log(await res.json());require 'json'
require 'net/http'
uri = URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor')
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.put(uri.path, { callback_url: 'https://my-server.com/hook' }.to_json,
'Content-Type' => 'application/json')
end
puts res.bodyStats
Сводка по всем вашим crawler-ам: параллельность, глубина очереди, количество завершённых/неуспешных задач и разбивка по истории.
# All-time summary
curl 'https://api.crawlbase.com/crawler/YOUR_TOKEN/stats'
# Same, filtered to a date range (YYYY-MM-DD bounds, inclusive)
curl 'https://api.crawlbase.com/crawler/YOUR_TOKEN/stats?history_from=2026-04-01&history_to=2026-04-30'import requests
# All-time summary
res = requests.get('https://api.crawlbase.com/crawler/YOUR_TOKEN/stats')
print(res.json())
# Same, filtered to a date range (YYYY-MM-DD bounds, inclusive)
res = requests.get('https://api.crawlbase.com/crawler/YOUR_TOKEN/stats?history_from=2026-04-01&history_to=2026-04-30')
print(res.json())// All-time summary
const all = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/stats');
console.log(await all.json());
// Same, filtered to a date range (YYYY-MM-DD bounds, inclusive)
const range = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/stats?history_from=2026-04-01&history_to=2026-04-30');
console.log(await range.json());require 'net/http'
# All-time summary
puts Net::HTTP.get(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/stats'))
# Same, filtered to a date range (YYYY-MM-DD bounds, inclusive)
puts Net::HTTP.get(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/stats?history_from=2026-04-01&history_to=2026-04-30'))Очистка crawler-а
Немедленно очищает очередь crawler-а - все ещё не обработанные URL удаляются. Используйте это, чтобы восстановиться после неконтролируемого продьюсера или очистить пакет, который больше не нужно обрабатывать. Откатить нельзя.
curl -X POST 'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/purge'import requests
res = requests.post('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/purge')
print(res.json())const res = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/purge', { method: 'POST' });
console.log(await res.json());require 'net/http'
res = Net::HTTP.post(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/purge'), nil)
puts res.bodyВсе URL в очереди этого crawler-а удаляются - никакого мягкого удаления или восстановления нет. Если нужно удалить только один URL, используйте Delete Job.
Удаление crawler-а
Полностью удаляет crawler - очищает очередь и снимает crawler с регистрации, так что он больше не отображается в вашей консоли и в статистике. В отличие от purge, который только очищает очередь и оставляет crawler, delete убирает его целиком. Откатить нельзя.
curl -X POST 'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/delete'import requests
res = requests.post('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/delete')
print(res.json())const res = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/delete', { method: 'POST' });
console.log(await res.json());require 'net/http'
res = Net::HTTP.post(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/delete'), nil)
puts res.bodyCrawler и всё, что ещё находится в его очереди, теряются навсегда - никакого мягкого удаления или восстановления нет. Если нужно только очистить очередь, но сохранить crawler, используйте Purge.
Удаление одной задачи
Удаляет один URL из очереди по его RID - идентификатору запроса, возвращённому при push URL.
curl -X POST 'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/delete_job?rid=YOUR_RID'import requests
res = requests.post('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/delete_job?rid=YOUR_RID')
print(res.json())const res = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/delete_job?rid=YOUR_RID', { method: 'POST' });
console.log(await res.json());require 'net/http'
res = Net::HTTP.post(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/delete_job?rid=YOUR_RID'), nil)
puts res.bodyПоиск задачи по RID
Узнайте, на какой стадии запрос. Возвращает QUEUED с метаданными очереди, если он ещё ожидает, или NOT_QUEUED, если он уже обойдён (или так и не попал в очередь).
curl 'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/find_by_rid/YOUR_RID'import requests
res = requests.get('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/find_by_rid/YOUR_RID')
print(res.json())const res = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/find_by_rid/YOUR_RID');
console.log(await res.json());require 'net/http'
puts Net::HTTP.get(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/find_by_rid/YOUR_RID')){
"status": "QUEUED",
"request_info": {
"rid": "YOUR_RID",
"url": "YOUR_URL",
"retry": 3,
"created_at": 1600494969.189415
}
}{
"status": "NOT_QUEUED",
"request_info": {
"rid": "YOUR_RID"
}
}Pause и unpause
Остановите crawler от взятия новой работы, не теряя его очередь. Push-нутые URL продолжают становиться в очередь, но crawler перестаёт их обрабатывать, пока вы не снимете паузу. Полезно для технических окон или для отступления, когда нижестоящая система нездорова.
# Pause - stops the crawler picking up new work
curl -X POST 'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/pause'
# Unpause - resumes processing
curl -X POST 'https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/unpause'import requests
# Pause - stops the crawler picking up new work
res = requests.post('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/pause')
print(res.json())
# Unpause - resumes processing
res = requests.post('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/unpause')
print(res.json())// Pause - stops the crawler picking up new work
const pause = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/pause', { method: 'POST' });
console.log(await pause.json());
// Unpause - resumes processing
const unpause = await fetch('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/unpause', { method: 'POST' });
console.log(await unpause.json());require 'net/http'
# Pause - stops the crawler picking up new work
puts Net::HTTP.post(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/pause'), nil).body
# Unpause - resumes processing
puts Net::HTTP.post(URI('https://api.crawlbase.com/crawler/YOUR_TOKEN/product-monitor/unpause'), nil).bodyПараметры
name|value|name|value. Удобно для передачи ID обратно в ваш обработчик. Только для crawler-ов в режиме webhook - игнорируется, когда crawler доставляет в Storage.1 – 10080 (от 1 минуты до 7 дней). Как только воркер начинает обход, этот таймер перестаёт действовать. Если запрос истекает в ожидании, вы получаете callback с HTTP 504 и cb_status=699. Опустите параметр (или установите 0), чтобы отключить. Агрессивные значения повышают долю неуспешных задач - выбирайте то, что отражает, как долго результат действительно полезен для вас.page_wait, scroll, country, scraper и т. д. - они применяются к каждому обходу.Когда использовать Crawler, а когда API
- Crawler: всякий раз, когда у вас более нескольких сотен URL для обработки, особенно на долгих горизонтах времени. Очередь сама занимается ретраями, расписанием и параллелизмом.
- Crawling API напрямую: когда результат нужен сразу: рендеринг страницы для пользовательского запроса, AI-агент, получающий контекст, и т. п.