关于 scraperapi-async
此技能介绍如何通过 ScraperAPI 在后台提交抓取任务,适用于处理大量 URL 或响应较慢的目标。内容涵盖批量提交、重试、状态查询和 Webhook 交付。
主要功能
- 01提交单个及批量任务
- 02批量请求最多支持 50,000 个 URL
- 03通过查询或 Webhook 获取结果
- 04任务最多重试 24 小时
- 05处理 PDF 和图像响应
适用场景
- 01异步抓取大量 URL
- 02通过 Webhook 接收完成结果
- 03采集 PDF 等二进制内容
- 04用元数据跟踪批次任务
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scraperapi/ scraperapi-skills --skill scraperapi-async安装后在 Claude Code 中输入/scraperapi-async确认已加载。
详细介绍
ScraperAPI 异步任务 API
异步 API 会在后台提交抓取任务,并在最多 24 小时内重试,以尽可能提高成功率。你可以通过轮询状态 URL 获取结果,也可以通过 webhook 自动接收结果。
何时不应使用异步 API
- 单个 URL,且需要立即获取结果 → 使用标准 API(
api.scraperapi.com)——更简单,并会直接返回结果。 - 需要跨站点跟踪链接 → 使用 Crawler。
- 需要定期安排抓取任务 → 使用 DataPipeline。
适用于以下情况:抓取 20 个以上的 URL、目标站点速度较慢或不稳定、希望通过 webhook 接收结果,或需要抓取 PDF/图片。
端点
| 操作 | 方法 | URL |
|---|---|---|
| 提交单个任务 | POST | https://async.scraperapi.com/jobs |
| 提交批量任务(最多 50k) | POST | https://async.scraperapi.com/batchjobs |
| 检查 / 获取任务 | GET | https://async.scraperapi.com/jobs/<jobId> |
| 取消任务 | DELETE | https://async.scraperapi.com/jobs/<jobId> |
身份验证:在 JSON 请求正文中使用 apiKey(注意:apiKey 使用驼峰命名,与标准 API 的 api_key 不同)。
单个任务
import os, requests, time
API_KEY = os.environ["SCRAPERAPI_API_KEY"]
# Submit
r = requests.post(
"https://async.scraperapi.com/jobs",
json={
"apiKey": API_KEY,
"url": "https://example.com/product/123",
"apiParams": {
"render": True,
"country_code": "us",
}
}
)
job = r.json()
# {"id": "...", "status": "running", "statusUrl": "...", "url": "..."}
# Poll
def poll(status_url, interval=5, max_wait=120):
deadline = time.time() + max_wait
while time.time() < deadline:
data = requests.get(status_url).json()
if data["status"] == "finished":
return data["response"]["body"]
if data["status"] == "failed":
raise RuntimeError(f"Job failed: {data.get('failReason')}")
time.sleep(interval)
raise TimeoutError("Job did not finish in time")
html = poll(job["statusUrl"])
已完成任务的响应格式:
{
"id": "...",
"status": "finished",
"statusUrl": "...",
"url": "https://example.com/product/123",
"response": {
"headers": { "content-type": "text/html", "sa-final-url": "...", "sa-statuscode": "200" },
"body": "<!doctype html>...",
"statusCode": 200
}
}
批量任务(最多 50,000 个 URL)
jobs = requests.post(
"https://async.scraperapi.com/batchjobs",
json={
"apiKey": API_KEY,
"urls": [
"https://example.com/page/1",
"https://example.com/page/2",
# ... up to 50,000
],
"apiParams": {"country_code": "us"}
}
).json()
# Returns a list of {id, status, statusUrl, url} — one per submitted URL
results = [poll(job["statusUrl"]) for job in jobs]
对于超过 50,000 个 URL 的工作负载,请拆分为多个批量请求。批次较大时,请使用 webhook(见下文)而不是轮询——依次轮询 10,000 个状态 URL 会很慢。
Webhook 回调
使用 webhook 接收结果,无需轮询。抓取完成后,ScraperAPI 会将已完成任务的负载通过 POST 请求发送到你的 URL。
requests.post(
"https://async.scraperapi.com/jobs",
json={
"apiKey": API_KEY,
"url": "https://example.com/",
"callback": {
"type": "webhook",
"url": "https://yourapp.com/scraperapi/callback"
}
}
)
Webhook 工作机制:
- 默认情况下,只有成功的任务会触发回调。
- 设置
"expectUnsuccessReport": true也可接收失败任务的负载。 - ScraperAPI 会重试 3 次投递;如果全部失败,任务将被取消。
- Webhook URL 必须可公开访问。
- 无需服务器即可进行测试,请使用 webhook.site。
失败任务的回调负载:
{
"id": "...",
"attempts": 50,
"status": "failed",
"failReason": "failed_due_to_timeout",
"url": "https://example.com/"
}
所有请求正文参数
{
"apiKey": "YOUR_KEY",
"url": "https://example.com",
"urls": ["url1", "url2"],
"method": "GET",
"headers": { "Accept-Language": "en-US" },
"body": "foo=bar",
"callback": { "type": "webhook", "url": "https://..." },
"expectUnsuccessReport": false,
"timeoutSec": 600,
"meta": { "jobLabel": "batch-42" },
"apiParams": {
"autoparse": false,
"country_code": "us",
"keep_headers": false,
"device_type": "desktop",
"follow_redirect": true,
"premium": false,
"ultra_premium": false,
"render": false,
"wait_for_selector": ".content",
"screenshot": false,
"retry_404": false,
"output_format": "html",
"max_cost": 10
}
}
Async 专属参数
| 参数 | 类型 | 用途 |
|---|---|---|
expectUnsuccessReport | 布尔值 | 也接收失败任务的 webhook 负载 |
timeoutSec | 整数 | 覆盖默认任务超时时间(秒) |
meta | 对象 | 自定义元数据——在每个响应 / 回调中原样返回,以便关联 |
meta 特别适用于跟踪任务所属的批次或工作流:
{ "meta": { "batchId": "run-2024-06", "sourceFile": "urls.csv" } }
向目标站点传递 POST 请求
requests.post(
"https://async.scraperapi.com/jobs",
json={
"apiKey": API_KEY,
"url": "https://api.example.com/search",
"method": "POST",
"headers": {"content-type": "application/x-www-form-urlencoded"},
"body": "query=scraperapi&page=1",
}
)
二进制响应(PDF 和图片)
当目标 URL 返回二进制内容时,响应正文会以 Base64 编码,并存放在
response.base64EncodedBody 中。
import base64
r = requests.post(
"https://async.scraperapi.com/jobs",
json={"apiKey": API_KEY, "url": "https://example.com/report.pdf"}
)
job = r.json()
# ... wait or poll ...
result = requests.get(job["statusUrl"]).json()
pdf_bytes = base64.b64decode(result["response"]["base64EncodedBody"])
with open("report.pdf", "wb") as f:
f.write(pdf_bytes)
保留政策
任务结果最多保存 72 小时(保证保存 24 小时),从任务完成后开始计算。 此后数据将被删除——如需再次获取,请重新提交任务。
请在保留期限结束前获取结果。对于较长的流水线,建议使用 webhook,以便结果在任务完成后立即推送到你的系统。
错误处理
| 状态 | 含义 | 操作 |
|---|---|---|
任务 finished,statusCode: 200 | 成功 | 使用 response.body |
任务 finished,statusCode: 403 | 目标站点阻止了抓取 | 在 apiParams 中使用 premium: true 重试 |
任务 failed,failReason: failed_due_to_timeout | 重试 24 小时后仍超时 | 检查目标站点是否可访问;尝试设置 render: false |
| 提交时 HTTP 401 | API 密钥错误 | 检查 SCRAPERAPI_API_KEY |
| 提交时 HTTP 403 | 额度不足或超出套餐限制 | 检查控制面板 |
| 提交时 HTTP 429 | 并发提交过多 | 暂停一段时间,然后分批重新提交 |
在 apiParams 中使用 max_cost 限制每个请求的额度消耗——超出上限的请求会返回 403,而不会消耗超出预期的额度。
积分消耗
Async API 与 Standard API 的积分消耗相同:
| 请求类型 | 积分 |
|---|---|
| Standard | 1 |
render: true | 10 |
premium: true | 10 |
ultra_premium: true | 30 |
| 失败的请求 | 0 |
在所有重试均已耗尽后仍失败的异步任务不会扣费。