mcpField
S
scraperapi-async

scraperapi-async

github.com/scraperapi数据与数据库10109 次安装12 周前更新
代码仓库

关于 scraperapi-async

此技能介绍如何通过 ScraperAPI 在后台提交抓取任务,适用于处理大量 URL 或响应较慢的目标。内容涵盖批量提交、重试、状态查询和 Webhook 交付。

主要功能

  1. 01提交单个及批量任务
  2. 02批量请求最多支持 50,000 个 URL
  3. 03通过查询或 Webhook 获取结果
  4. 04任务最多重试 24 小时
  5. 05处理 PDF 和图像响应

适用场景

  1. 01异步抓取大量 URL
  2. 02通过 Webhook 接收完成结果
  3. 03采集 PDF 等二进制内容
  4. 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
提交单个任务POSThttps://async.scraperapi.com/jobs
提交批量任务(最多 50k)POSThttps://async.scraperapi.com/batchjobs
检查 / 获取任务GEThttps://async.scraperapi.com/jobs/<jobId>
取消任务DELETEhttps://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 401API 密钥错误检查 SCRAPERAPI_API_KEY
提交时 HTTP 403额度不足或超出套餐限制检查控制面板
提交时 HTTP 429并发提交过多暂停一段时间,然后分批重新提交

在 apiParams 中使用 max_cost 限制每个请求的额度消耗——超出上限的请求会返回 403,而不会消耗超出预期的额度。

积分消耗

Async API 与 Standard API 的积分消耗相同:

请求类型积分
Standard1
render: true10
premium: true10
ultra_premium: true30
失败的请求0

在所有重试均已耗尽后仍失败的异步任务不会扣费。

文档

评论

支持 Markdown