PHP
Официальный PHP-клиент для платформы Crawlbase. PSR-совместимый, устанавливается через Composer, работает с PHP 7.4+ - один пакет, все API, разумные значения по умолчанию.
Как устроен SDK
PHP SDK - это тонкая обёртка над тем же HTTP API, который описан в API Reference. Каждый параметр Crawling API, который вы добавили бы как query string в прямом HTTP-вызове, доступен в SDK как ключ в массиве опций - имена, значения по умолчанию и поведение соответствуют один к одному. SDK не добавляет ни одного параметра; SDK не скрывает ни одного параметра.
Что вы получаете, используя его вместо cURL или Guzzle напрямую:
- URL-кодирование, валидация параметров и парсинг ответов работают из коробки.
- Автозагрузка PSR-4 - подключается к любому современному PHP-фреймворку (Laravel, Symfony, Slim) без церемоний.
- По одному клиентскому классу на каждый Crawlbase API, все с одинаковой формой конструктора и вызовов.
- Разумные значения по умолчанию (тайм-аут 90 секунд, автоматический парсинг JSON для ответов
format=json, тела в кодировке UTF-8).
Исходники на github.com/crawlbase/crawlbase-php. Issues и PR приветствуются.
Установка
Последняя версия на Packagist. Требуется PHP 7.4+; протестировано вплоть до PHP 8.3.
composer require crawlbase/crawlbase
# Or add to composer.json directly:
# "crawlbase/crawlbase": "^1.0"Аутентификация
Каждый Crawlbase API использует одну и ту же модель аутентификации по token. На одном аккаунте существуют два типа токенов:
- Normal Token (TCP) - для статического HTML, JSON-эндпоинтов, всего, что не требует браузера. Быстрее и дешевле.
- JavaScript Token
- для SPA, лениво загружаемых лент, всего, что скрывает контент за клиентским рендерингом. Обязателен для использования
page_wait,ajax_wait,scrollиcss_click_selector.
Используйте переменные окружения (или конфиг вашего фреймворка - config() в Laravel, параметры в Symfony) в production. SDK сам не читает env-переменные - это сделано намеренно, чтобы вы контролировали, откуда берутся учётные данные. Шаблон:
<?php
require 'vendor/autoload.php';
use Crawlbase\CrawlingAPI;
// Pick the right token at instantiation; the SDK doesn't switch
// tokens per-call, so keep two clients if you alternate.
$api = new CrawlingAPI(['token' => getenv('CRAWLBASE_TOKEN')]);
$js = new CrawlingAPI(['token' => getenv('CRAWLBASE_JS_TOKEN')]);
$api->get('https://github.com/anthropic');
$js->get('https://feed.example.com', ['page_wait' => 2000]);Полная модель токенов и расположение в дашборде — на странице Authentication.
Быстрый старт
Три строки от autoload до полученного HTML:
<?php
require 'vendor/autoload.php';
$api = new \Crawlbase\CrawlingAPI(['token' => 'YOUR_TOKEN']);
$res = $api->get('https://github.com/anthropic');
if ($res->statusCode == 200) {
echo $res->body;
}Ветвитесь по ->statusCode (HTTP-статус SDK к Crawlbase) и ->headers->pc_status (вердикт Crawlbase - см. Ошибки ниже) при принятии решения о повторе. Передайте ['format' => 'json'], чтобы получить JSON-конверт вместо сырого содержимого страницы.
Все API в одном пакете
У каждого Crawlbase API есть соответствующий клиентский класс. Один и тот же конструктор, те же глаголы get / post.
<?php
use Crawlbase\{CrawlingAPI, ScraperAPI, LeadsAPI, ScreenshotsAPI, StorageAPI};
$token = ['token' => 'YOUR_TOKEN'];
$crawl = new CrawlingAPI($token); // general-purpose page fetch
$scraper = new ScraperAPI($token); // parsed JSON for supported sites
$leads = new LeadsAPI($token); // domain-scoped email extraction (legacy)
$shots = new ScreenshotsAPI($token); // screenshots of any URL
$storage = new StorageAPI($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.Распространённые паттерны
JavaScript-рендеринг
Для SPA, лениво загружаемых лент и страниц, где исходный HTML пуст, создавайте инстанс с JavaScript token и передавайте любую комбинацию page_wait, ajax_wait, scroll и css_click_selector. Порядок, о котором стоит думать: фиксированное ожидание, затем network-idle, затем скролл для ленивой загрузки, затем клик по любому блокирующему элементу UI.
$api = new \Crawlbase\CrawlingAPI(['token' => 'YOUR_JS_TOKEN']);
$res = $api->get('https://spa.example.com', [
'page_wait' => 2000,
'ajax_wait' => true,
'scroll' => true,
]);Использование встроенного scraper'а
Пропустите парсер целиком на поддерживаемых сайтах. Передайте 'scraper' => 'NAME', и тело ответа станет JSON-строкой со структурированными полями, описанными на странице конкретного scraper'а.
<?php
use Crawlbase\ScraperAPI;
$api = new ScraperAPI(['token' => 'YOUR_TOKEN']);
$res = $api->get('https://www.amazon.com/dp/1098145356',
['scraper' => 'amazon-product-details']);
$data = json_decode($res->body, true);
echo $data['name'] . ' - ' . $data['price'];Гео-маршрутизация
Передайте 'country' => 'ISO', чтобы маршрутизировать crawl через выходные узлы указанной страны. Используйте всякий раз, когда целевой сайт отдаёт локализованный контент в зависимости от IP.
$api = new \Crawlbase\CrawlingAPI(['token' => 'YOUR_TOKEN']);
// Hit the German Amazon catalog from a German residential IP
$res = $api->get('https://www.amazon.com/dp/1098145356', ['country' => 'DE']);Повторы с backoff
Рекомендуемая форма повторов: экспоненциальный backoff с ограничением в 3–5 попыток, повторять только на временных ошибках (5xx или пустое тело), не повторять на 4xx.
<?php
use Crawlbase\CrawlingAPI;
function crawl(CrawlingAPI $api, string $url, int $attempts = 5) {
for ($i = 0; $i < $attempts; $i++) {
$res = $api->get($url);
if ($res->statusCode === 200 && (int) $res->headers->pc_status === 200) {
return $res;
}
if ($res->statusCode >= 400 && $res->statusCode < 500) {
throw new RuntimeException("client error {$res->statusCode}: $url");
}
usleep((int) (mt_rand() / mt_getrandmax() * pow(2, $i) * 1_000_000));
}
throw new RuntimeException("Failed: $url");
}Async-краулы и вебхуки
Режим fire-and-forget. Вызов SDK немедленно возвращается с rid; Crawlbase отправит POST с результатом на ваш callback URL, когда страница будет готова. Полезно для пакетных задач и медленных целей.
$api = new \Crawlbase\CrawlingAPI(['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 Laravel / Symfony / Slim webhook receives a POST with:
// { rid, url, original_status, pc_status, body }Для очень больших объёмов (миллионы URL) используйте Enterprise Crawler, который стоит перед тем же async-конвейером.
Sticky-сессии
Некоторые сценарии требуют одного и того же residential IP между несколькими вызовами. Передайте cookies_session со стабильным идентификатором, и Crawlbase будет переиспользовать тот же выходной узел в течение примерно 30 минут.
$api = new \Crawlbase\CrawlingAPI(['token' => 'YOUR_JS_TOKEN']);
$session = "checkout-{$userId}";
$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]);Ошибки и повторы
Платформа возвращает два статус-кода в каждом ответе: собственный ->statusCode SDK (HTTP-статус запроса к самой Crawlbase) и ->headers->pc_status (вердикт Crawlbase по целевому сайту - полный список см. в таблице ошибок Crawling API). Всегда ветвитесь по ->headers->pc_status при принятии решения о повторе - целевой сайт может вернуть 200 с пустым телом, и тогда ->statusCode будет 200, а ->headers->pc_status - 520.
$res = $api->get($url);
$pc = (int) $res->headers->pc_status;
switch (true) {
case $pc === 200:
use_body($res->body);
break;
case in_array($pc, [520, 525], true):
// 520 = empty body, 525 = anti-bot couldn't be solved.
// Switch to JS token and retry.
retry_with_js_token($url);
break;
case in_array($pc, [521, 522, 523], true):
// Target unreachable or timed out. Retry with backoff.
schedule_retry($url);
break;
default:
$logger->error('crawl failed', ['url' => $url, 'pc_status' => $pc]);
}Все повторы запросов к платформе бесплатны - только успешные ответы (pc_status: 200) учитываются в вашей квоте.
Производительность и лучшие практики
- Переиспользуйте один клиент на token. Создавайте его один раз при старте приложения (service provider в Laravel, service container в Symfony) и инжектьте везде - каждый экземпляр открывает собственное соединение.
- Используйте самый дешёвый token, который справляется. Не используйте JavaScript token по умолчанию «на всякий случай» - запросы с Normal token быстрее и используют меньше параллелизма. Переходите на JS только тогда, когда ответ Normal пустой или заблокирован анти-бот-защитой.
- Предпочитайте
ajax_wait, а неpage_wait. Фиксированные задержки расходуют конкурентность на каждом запросе, даже на быстрых. - Для пакетных задач: async + webhook или отправка в Enterprise Crawler. Воркеры очереди, синхронно вызывающие SDK, насытят ваш лимит конкурентности; async + webhook освобождает слот в момент постановки запроса в очередь.
- Следите за заголовком ответа
remaining. В нём указано, сколько слотов конкурентности у вас осталось.
Справочник методов
Все клиентские классы имеют одинаковую поверхность. Конструктор принимает массив опций; глаголы зеркалят соответствующие HTTP-методы.
'timeout' в секундах (по умолчанию 90).$options сопоставляет любой параметр Crawling API с его значением.$data - это body: передайте массив для form-encoded или строку для raw.Форма ответа - публичные свойства объекта ответа, возвращаемого каждым методом:
format=json / scraper=).->headers->pc_status: вердикт Crawlbase по целевому сайту (ветвитесь по нему для решений о повторе).->headers->original_status: HTTP-статус, который целевой сайт вернул Crawlbase.->headers->storage_url/->headers->rid: устанавливаются, когда вызов содержал'store' => true.