状态码
Crawlbase 在每个响应中返回两个状态信号:标准的 HTTP 状态,以及描述 Crawlbase 所做操作的 cb_status 头。下面是每种组合的含义。
两种状态,两个问题
大多数 HTTP API 只返回一个状态码。Crawlbase 返回两个,因为爬取涉及两层:Crawlbase 的基础设施,以及其背后的目标站点。
您向 Crawlbase 发起的请求的状态。
200 表示爬取成功;520 表示爬取失败,cb_status 会说明原因;其他 4xx/5xx 状态码表示请求在爬取之前就被拒绝。Crawlbase 对本次爬取的判定,基于其自身对屏蔽、重定向和内容的检查。
200 表示页面可用;其他状态码描述出了什么问题。目标站点返回的原始 HTTP 状态。当站点本身返回需要您处理的非 200 状态(404、403 等)时很有用。
思维模型
始终先检查 HTTP 状态。如果是 200,再检查 cb_status。如果它也是 200,再检查 original_status 是否有站点端错误。
HTTP 状态码
Crawlbase 本身返回给您客户端的内容。
| 状态码 | 含义 | 操作 |
|---|---|---|
200 | 请求已处理。请检查 cb_status 以获取结果。 | 继续查看 cb_status |
400 | 无效请求:url 缺失、未进行 URL 编码或过长,或某个参数的值无效。 | 修正请求;原样重试无济于事 |
401 | token 缺失或无效。 | 验证 token;检查是否已被重置 |
402 | 此工作区已达到每月支出上限。 | 在控制台中提高上限,或等待下一个周期 |
403 | 账户已被封禁(例如免费额度已用完且未设置账单),或已达到账户支出限额。 | 查看控制台中的账单页面 |
429 | 此 token 和目标域名已达到速率限制。 | 退避后重试;参见 Rate Limits |
500 | Crawlbase 内部错误。罕见且为暂时性。 | 退避后重试;查看状态页面 |
503 | 服务暂时不可用。 | 退避后重试 |
504 | 请求在爬取完成前超时(cb_status 同样为 504)。不计费。 | 退避后重试 |
520 | 爬取失败。cb_status 会说明原因。不计费。 | 读取 cb_status 并参照下方表格处理 |
cb_status 状态码
爬取过程中发生了什么。无论成功与否,每个爬取响应都会以 cb_status 响应头返回该值(使用 format=json 时也包含在响应体中)。此前称为 pc_status,该名称仍作为别名一并发送。
成功
| 状态码 | 含义 |
|---|---|
200 | 页面爬取成功。响应体为目标页面的 HTML 或 JSON。original_status 也可能是 404、410 或重定向:这些都是有效的应答,计为成功爬取并会计费。 |
207 | 站点返回了 200,但响应体为空。计为成功并会计费;如果您预期有内容,请使用 JavaScript token 重试。 |
目标站点返回错误
Crawlbase 已抵达站点,但站点拒绝了该请求。original_status 保存站点自身返回的状态,以下情况均不计费。404 或 410 在这里不算错误:它们会以 cb_status 200 返回。
| 状态码 | 含义 |
|---|---|
704 | 站点返回了其他非成功状态。请读取 original_status 并将其作为站点的应答处理,或将其加入 custom_success_codes 以照样获取响应体。 |
705 | 站点返回了 403,通常意味着被屏蔽。请降低请求速率,排查原因后再重试。 |
706 | 站点返回了 429,正在对您限流。请退避并降低请求速率。 |
被屏蔽或失败
| 状态码 | 含义 | 尝试方法 |
|---|---|---|
503 | Crawlbase 识别出了屏蔽页面或 CAPTCHA 页面。 | 从 Normal token 切换到 JavaScript token;如果已在使用 JavaScript,请退避后重试 |
595 | 页面上未找到 css_click_selector 指定的元素。 | 修正选择器,或添加回退,例如 #start-button,body |
599 | Crawlbase 内部错误。 | 退避后重试;如果问题持续,请将 rid 发送给支持团队 |
5xx-7xx | 其他任何 5xx、6xx 或 7xx 状态码都表示内部故障或特定于站点的故障。均不计费。 | 限定次数重试;如果问题持续,请将 rid 发送给支持团队 |
解读响应
curl -i 'https://api.crawlbase.com/?token=YOUR_TOKEN&url=https%3A%2F%2Fexample.com'
# HTTP/1.1 200 OK
# cb_status: 200
# original_status: 200
# url: https://example.com/
# content-type: text/htmlfrom crawlbase import CrawlingAPI
api = CrawlingAPI({'token': 'YOUR_TOKEN'})
res = api.get('https://example.com')
# Layer 1: did the crawl succeed? 520 means it failed.
if res['status_code'] != 200:
raise RuntimeError(f"Crawl failed: {res['status_code']}, cb_status {res['cb_status']}")
# Layer 2: did Crawlbase get content? 207 means an empty page.
if res['cb_status'] == 207:
raise RuntimeError("Empty page; retry with the JavaScript token")
# Layer 3: did the target site return content?
if res['original_status'] != 200:
print(f"Site returned {res['original_status']}")
print(res['body'])