大多数抓取教程都向你展示如何获取一个页面并立即解析它。这种同步循环在你只需要少量页面时运行良好,但当你需要数千个页面时,你的脚本就会把时间都花在等待上:提交一个 URL,阻塞直到响应返回,解析,重复。重试、队列、代理轮换和渲染都堆叠在同一个线程上,一个响应缓慢的目标就会拖慢整个运行。在大规模场景下,你需要一种完全不同的方式。
本指南向你展示如何使用 Crawlbase Crawler 提取数据,这是专为批量任务构建的异步推送式产品。你无需等待每个请求,而是将一批 URL 推送给 Crawler,它在自己的基础设施上大规模爬取,然后将每个完成的结果推送到你控制的 webhook 端点。提交和获取是解耦的,因此你的代码永远不会因等待某个页面而阻塞。学完本文,你将拥有一个可运行的回调服务器、一个命名的 crawler,以及一个推送 URL 并在另一端接收解析数据的脚本。
同步与异步:选择合适的工具
Crawlbase 提供两种获取页面的方式,区别在于时机,而非能力。Crawling API 是同步的:你发送请求,等待,已渲染的 HTML 在同一响应中返回。当你需要立即获取一个页面并希望结果内联时,它非常完美。
Crawler 是构建在同一引擎之上的异步层。你推送一个 URL,立即得到一个包含请求 ID 的确认,仅此而已。实际的爬取在 Crawlbase 服务器后台进行,当页面就绪时,结果会以 POST 方式发送到你的回调 URL。你永远不需要保持连接打开,因此你可以在几秒钟内提交数千个 URL,并让结果随着它们完成而流回到你的端点。
对于需要内联获取页面的交互式、一次性请求,使用 Crawling API。当你需要批量爬取时,请使用 Crawler:大型列表、重复任务,或任何在每个请求上阻塞会影响吞吐量的情况。Crawler 为你处理队列、重试、代理轮换和 JavaScript 渲染,并通过你的 webhook 返回完成的数据。
推送模型的工作原理
整个流程有三个活动部分,在编写代码之前把这三个部分都记清楚会很有帮助。
首先是crawler:你在控制台一次性创建的命名配置。它将回调 URL 与请求类型(普通或 JavaScript)绑定,以便引擎知道在哪里交付结果以及如何渲染。其次是推送请求:你用 token、目标 URL 和 crawler 名称调用 API,它返回一个包含唯一请求 ID(RID)的 JSON 确认。第三是回调:当页面被爬取后,Crawlbase 向你的回调 URL 发送一个包含页面内容和相同 RID 的 HTTP POST,这样你就可以将每次交付与你提交的 URL 匹配起来。
你的回调端点必须满足两个条件。它必须能够被 Crawlbase 服务器公开访问,并且必须快速响应:在几百毫秒内用 200、201 或 204 状态码响应 POST 请求。内容以 GZIP 压缩方式到达,默认为 HTML;你可以通过在请求中设置 format 来请求解析后的 JSON。由于工作是异步的,你在接收端的任务就是快速确认并将有效载荷交给队列或数据库,而不是在线内进行繁重处理。
你将构建什么
一个完整的 Python 往返流程。你将搭建一个小型 Flask webhook 来接收已爬取的页面,将其公开到互联网以便 Crawlbase 可以访问,在控制台创建一个指向该公共 URL 的命名 crawler,最后使用官方 crawlbase 客户端推送目标 URL。我们将使用公开测试页面,这样你可以在将其指向真实目标之前运行每个步骤。
设置环境
你需要 Python 3.8 或更高版本。确认你的版本,创建虚拟环境以隔离依赖项,然后安装两个库:用于 webhook 服务器的 Flask 和用于推送请求的官方 Crawlbase 客户端。
python --version python -m venv crawler_env source crawler_env/bin/activate pip install flask crawlbase
在 Windows 上,使用 crawler_env\Scripts\activate 代替 source 行来激活环境。你还需要从控制台获取你的 Crawlbase token。Crawlbase 提供两种 token 类型:用于普通 HTTP 请求的普通 token,以及用于在真实浏览器中客户端渲染内容的 JavaScript token。根据你所针对的网站选择合适的 token;大多数现代页面需要 JavaScript token。
步骤 1:构建接收已爬取数据的 webhook
回调端点是完成页面的落地之处。创建一个名为 webhook.py 的文件。处理程序读取 POST 主体,记录 RID 以便你将其与推送响应关联,并立即返回 200。Flask 会为你解压 GZIP 主体,因此当你读取时内容已经是纯文本。
from flask import Flask, request app = Flask(__name__) @app.route("/crawlbase", methods=["POST"]) def webhook(): rid = request.headers.get("rid") original_url = request.headers.get("original_url") body = request.get_data(as_text=True) print(f"Received RID {rid} for {original_url}") print(f"Payload size: {len(body)} bytes") # Hand the payload to a queue or database here; keep this fast. return "", 200 if __name__ == "__main__": app.run(port=3000)
这里有几个细节很重要。Crawlbase 在 rid 头中发送请求 ID,在 original_url 中发送已爬取的 URL,因此你永远不必猜测某次交付属于哪个提交。处理程序不做任何繁重工作:它确认并返回。200 毫秒的响应窗口是严格的,因此任何缓慢的操作(解析、写入慢速存储、调用另一个服务)都应该放在后台队列中,而不是在请求内部。启动服务器并让它在自己的终端中运行。
python webhook.py
步骤 2:将本地服务器暴露到互联网
Crawlbase 服务器必须能够访问你的回调,而 localhost 上的服务器从外部是无法访问的。在开发期间,最简单的解决方案是使用 ngrok 这样的隧道工具,它为你的本地端口提供一个公开的 HTTPS URL。在 webhook 仍在端口 3000 上运行的情况下,打开第二个终端并启动隧道。
ngrok http 3000
ngrok 会打印一个公开的转发 URL,类似于 https://random-id.ngrok-free.app。你的完整回调 URL 是该主机加上 Flask 应用中的路由,即 https://random-id.ngrok-free.app/crawlbase。也请保持此终端打开;每次重启隧道时 URL 会改变。在生产环境中,你会将 crawler 指向自己基础设施上一个真实的稳定端点。
隧道是一种开发便利手段,而非部署策略。对于真实工作负载,请将 webhook 托管在具有稳定公开 URL 的服务上,并在信任之前验证每个传入请求,例如检查 RID 是否与你实际推送的某个请求匹配。将回调视为不受信任的公开端点,因为它就是这样的。
步骤 3:在控制台创建 crawler
推送请求需要一个命名的 crawler,这样引擎才知道在哪里交付结果。在你的 Crawlbase 控制台中,转到 Crawler 部分并创建一个新的 crawler。给它一个唯一的名称,粘贴你的公开回调 URL(ngrok URL 加 /crawlbase),并选择请求类型:普通 HTML 选普通,客户端渲染页面选 JavaScript。保存后,crawler 会出现在你的列表中,准备好接收推送。
你选择的名称就是你在每次推送请求中传递的值,所以保持简单易记。常见的模式是每个项目或每个数据源一个 crawler,每个都指向你的服务器能够区分的路由。
Crawler 是大规模抓取的异步推送式方法。在几秒钟内推送数千个 URL,让完成的页面流回你的 webhook,同时引擎在自己的基础设施上处理队列、重试、代理轮换和 JavaScript 渲染。在免费套餐上创建你的第一个 crawler 并将其指向公开测试页面。
步骤 4:向 Crawler 推送 URL
webhook 已启动、隧道已打开、crawler 已创建,你准备好推送了。官方 crawlbase 客户端封装了 API,因此推送只需一次带有两个额外选项的 get 调用:将 callback 设为 true,将 crawler 设为你注册的名称。创建一个名为 push.py 的文件。
from crawlbase import CrawlingAPI api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) target = "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html" response = api.get(target, { "callback": "true", "crawler": "my-crawler", "format": "json", }) print(response["body"])
使用 python push.py 运行它。响应不是页面内容,而是带有请求 ID 的即时确认,这正是异步的含义:调用在爬取完成之前返回。你会得到类似这样的内容。
{ "rid": "e2bbac4e7ea9a4c4be57d2a4" }
一两秒后,已爬取的页面到达你的 webhook。检查运行 webhook.py 的终端,你会看到打印出相同的 RID,确认整个往返流程完成:引擎在后台爬取了页面,并将完成的结果以 POST 方式发送到你的回调。在推送时将 format 设为 json 意味着交付的有效载荷是解析后的 JSON 而非原始 HTML,这通常更适合下游处理。
批量推送
一个 URL 证明了配置是有效的;Crawler 的意义在于处理大量 URL。推送一个列表只需要一个循环,由于每次调用立即返回,你可以在几秒钟内提交大批量请求而无需等待任何单次爬取。Crawler 有一个宽裕的推送队列,因此你持续填充它,让结果按照自己的节奏到达 webhook。
from crawlbase import CrawlingAPI api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) urls = [ "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html", "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html", "https://books.toscrape.com/catalogue/soumission_998/index.html", ] for url in urls: response = api.get(url, { "callback": "true", "crawler": "my-crawler", "format": "json", }) print(f"Pushed {url} -> {response['body']}")
每次迭代返回自己的 RID,你的 webhook 在每次爬取完成时接收一个单独的 POST。在推送端存储 RID 列表,并在回调端与交付内容进行对账,这样你就可以发现任何从未回来的请求并重新推送它。这个对账循环是可靠批量管道的骨干,它自然地融入更大的可扩展网络数据管道。
验证和使用获取的数据
接收数据并不等同于信任数据。在有效载荷到达你的数据仓库之前,在回调端验证它:确认 RID 与你推送的某个请求匹配,检查 Crawlbase 报告的爬取状态码,并验证你期望的字段是否存在且非空。页面在 HTTP 层面可能成功返回,但重新设计或软屏蔽使你关注的内容缺失,因此快速的 schema 检查可以及早发现静默缺口。
验证通过后,获取的数据可以满足常见的业务需求:对竞争对手进行价格和库存监控、潜在客户和联系人丰富、市场和情感研究、模型训练集,或者将内部目录与外部来源保持同步。由于 Crawler 持续交付结果而不是一次性的阻塞批次,它自然适合流式和增量管道,新数据在每个页面被爬取后立即到达。有关以大规模获取干净结果的更多信息,请参阅如何在不被封禁的情况下抓取网站。
如果你更倾向于路由自己的流量而不是使用推送模型,Smart AI Proxy 以直接端点的形式提供与 Crawling API 相同的住宅 IP 轮换,而 Crawling API 在你希望获取结构化字段而无需自己管理解析时,为支持的网站返回预解析的 JSON。
核心要点
- 设计上的异步。Crawler 将提交与获取解耦:你推送 URL 并立即得到 RID,然后结果在每次爬取完成时以 POST 方式发送到你的 webhook。
- 三个活动部分。控制台中的命名 crawler、携带你的 token 和 crawler 名称的推送请求,以及接收数据和匹配 RID 的回调端点。
- 快速响应。你的 webhook 必须公开可访问,并在大约 200 毫秒内以 2xx 状态码响应,因此确认后将繁重工作转移到队列中。
- 专为批量构建。由于每次推送立即返回,你可以在几秒钟内提交数千个 URL,让引擎处理队列、重试、代理和渲染。
- 验证后再信任。对账 RID 并检查期望字段是否存在,防止来自重新设计或软屏蔽的静默缺口进入你的数据。
常见问题
Crawler 和 Crawling API 有什么区别?
Crawling API 是同步的:你发送请求,已渲染的页面在同一响应中返回,非常适合一次性的交互式请求。Crawler 是构建在同一引擎之上的异步层:你推送一个 URL,立即得到一个请求 ID,完成的页面稍后交付到你的 webhook。对于内联结果使用 Crawling API,对于在每个请求上阻塞会限制吞吐量的批量任务使用 Crawler。
为什么我的 webhook 需要公开可访问?
Crawlbase 服务器通过向你的回调 URL 发送 HTTP POST 来交付已爬取的页面,因此它们必须能够通过互联网访问它。localhost 上的服务器在你的机器外部是不可见的,这就是为什么你在开发期间使用 ngrok 这样的隧道工具来公开它。在生产环境中,你将 webhook 托管在具有稳定公开 URL 的服务上。
推送请求返回什么?
它返回一个包含唯一请求 ID(RID)的小型 JSON 确认,而不是页面内容。这就是异步合同:调用立即返回,而爬取在后台运行。实际页面稍后到达你的 webhook,在其头部携带相同的 RID,以便你将每次交付与你提交的 URL 匹配起来。
我的回调需要多快响应?
大约 200 毫秒内,状态码为 200、201 或 204。Crawlbase 期望快速确认,因此你的处理程序应该读取有效载荷,将其交给队列或数据库,然后返回。任何缓慢的操作,如解析或写入慢速存储,都应该放在后台 worker 上而不是在请求内部。
我可以接收解析后的 JSON 而不是原始 HTML 吗?
可以。默认情况下 Crawler 交付 HTML,但你可以在推送请求中将 format 设为 JSON,有效载荷就会以解析后的形式到达。选择你的下游代码更喜欢的格式;JSON 通常更易于结构化提取,而 HTML 在你想要对整个页面运行自己的解析器时很方便。
如何使批量爬取更可靠?
跟踪你推送的每个 URL 的 RID,并将该列表与到达 webhook 的交付内容进行对账。任何从未到达的内容都可以重新推送。在接收端,通过确认 RID、检查报告的爬取状态并验证期望字段是否存在来验证每个有效载荷,这样带有缺失内容的成功响应就不会悄悄溜过去。
大规模爬取任何站点,无需与基础设施对抗。
Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。
