PHP
Crawlbase 平台的官方 PHP 客户端。PSR 兼容、可通过 Composer 安装、支持 PHP 7.4+,同一个包,所有 API,合理的默认值。
SDK 的设计结构
PHP SDK 是对 API Reference 中所记录的 HTTP API 的轻量封装。在原始 HTTP 调用中作为查询字符串附加的每个 Crawling API 参数,都可以通过 SDK 的 options 数组中的键访问:名称、默认值和行为均一一对应。SDK 不会额外添加任何参数,也不会隐藏任何参数。
相比直接使用 cURL 或 Guzzle,使用它能获得:
- 开箱即用的 URL 编码、参数校验和响应解析。
- PSR-4 自动加载:可无缝集成到任何现代 PHP 框架中(Laravel、Symfony、Slim)。
- 每个 Crawlbase API 对应一个客户端类,共享相同的构造函数和调用形式。
- 合理的默认值(90 秒超时、自动解析
format=json响应、UTF-8 编码的请求体)。
源码托管于 github.com/crawlbase/crawlbase-php。欢迎提交 Issue 和 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 模型进行认证。每个账号下有两种 token 类型:
- Normal Token (TCP) - 用于静态 HTML、JSON 端点以及任何不需要浏览器的场景。更快、更便宜。
- JavaScript Token
- 用于 SPA、懒加载内容流以及任何在客户端渲染中隐藏内容的场景。使用
page_wait、ajax_wait、scroll和css_click_selector时必需。
在生产环境中请使用环境变量(或您框架的配置:Laravel 的 config()、Symfony 的 parameters)。SDK 本身不会读取环境变量,这是有意为之,以便您完全掌控凭证的来源。模式如下:
<?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]);完整的 token 模型及在控制面板中的位置请参见 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(SDK 与 Crawlbase 之间的 HTTP 状态)和 ->headers->pc_status(Crawlbase 的判定结果,参见下文的 Errors)进行分支判断。传入 ['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。建议的执行顺序:先固定等待,再等待网络空闲,然后滚动以触发懒加载,最后点击任何拦截 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' 即可通过该国家的出口节点进行抓取。当目标站点根据 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']);带退避的重试
推荐的重试策略:指数退避,最多重试 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");
}异步抓取 + Webhook
即发即忘模式。SDK 调用立即返回一个 rid;页面就绪后,Crawlbase 会通过 POST 将结果推送到您的回调 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,它就部署在同一条异步管道之前。
粘性会话
有些流程需要在多次调用之间使用相同的住宅 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]);错误处理与重试
平台会在每个响应中返回两个状态码:SDK 自身的 ->statusCode(向 Crawlbase 发起请求的 HTTP 状态)和 ->headers->pc_status(Crawlbase 对目标站点的判定结果,完整列表参见 Crawling API errors table)。在决定是否重试时,始终应根据 ->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 复用单一客户端实例。 在应用启动时构建一次(Laravel 的 service provider、Symfony 的服务容器),然后在各处注入使用:每个实例都会打开自己的连接。
- 使用能完成任务的最便宜 token。 不要「以防万一」默认使用 JavaScript token:Normal-token 请求更快,并占用更少的并发额度。仅在 Normal 响应为空或被反爬虫拦截时,再升级到 JS。
- 优先使用
ajax_wait而非page_wait。 固定延迟会在每次请求(包括快请求)上消耗并发资源。 - 批量任务请使用 async + webhook,或推送到 Enterprise Crawler。 同步调用 SDK 的队列工作进程会迅速占满您的并发上限;async + webhook 在请求入队的瞬间就会释放槽位。
- 关注响应头中的
remaining。 它表示您当前剩余的并发槽位数。
方法参考
所有客户端类都共享相同的接口。构造函数接收一个选项数组;方法名与底层 HTTP 方法对应。
'timeout'(以秒为单位,默认 90)。$options 将任意 Crawling API 参数映射到对应的值。$data 是请求体:传数组则按表单编码,传字符串则按原始内容发送。响应结构:每个方法返回的响应对象上的公共属性如下:
format=json / scraper= 时为 JSON 字符串)。->headers->pc_status:Crawlbase 对目标站点的判定结果(重试决策应基于此字段)。->headers->original_status:目标站点返回给 Crawlbase 的 HTTP 状态码。->headers->storage_url/->headers->rid:当调用中携带'store' => true时会被设置。