什么是 Crawlee?请求队列与爬虫设计指南

什么是 Crawlee?

Scrapeless Agent Browser 为需要渲染和交互动态网页的自动化客户端提供受管的浏览器执行环境。

Crawlee 是一个开源的网页抓取与爬取框架,提供 JavaScript 和 Python 实现。Crawlee 围绕请求、爬虫处理器、执行资源以及结果存储来组织工作。框架负责协调哪些页面被处理以及记录如何保存;它不同于用于渲染页面的浏览器引擎,也不同于托管浏览器的服务。

当一个单页脚本扩展成一次爬取时,这种区分就变得有价值了。此时的挑战不再只是读取某个元素。你需要一份有边界的任务列表、一种发现更多 URL 的方式、清晰的重复请求规则,以及在浏览器关闭后仍然有用的记录格式。Crawlee 为这些工作提供组件,而你的应用程序则定义爬取的目的和可接受的结果。

Crawlee 为页面脚本添加了哪些内容

Crawlee 在用于获取页面和提取数据的代码之上添加了编排功能。 Crawlee 爬取框架 公开 HTTP 和浏览器爬取、请求存储、结果存储、资源感知的执行以及生命周期自定义功能。

普通的页面脚本从一个 URL 开始,以一些观察结果结束。爬虫还需要跟踪其前沿:那些已经被发现但尚未完成的工作。当处理器发现分类页面、详情页或分页链接时,这个前沿会扩展。一个持久化的请求队列可以让这些工作可见,而不是把它们隐藏在不断增长的浏览器标签页集合中。

处理程序仍然是应用程序代码。框架无法决定价格是否含税、一个标题是否属于当前产品,或者一个空列表是否意味着“没有结果”。必须明确地定义这些区分。如果处理程序接受不完整或不匹配的记录,那么即使爬虫处理了所有已排队的 URL,仍然可能生成不可用的数据集。

HTTP 爬虫和浏览器爬虫解决的是不同的问题

HTTP 爬虫获取响应以进行解析,而浏览器爬虫可以执行页面脚本并与渲染后的文档交互。正确的选择取决于所需内容在何处变为可用。

如果已下载的 HTML 中包含公共文章的文本,那么解析该响应可能就足够了。启动一个完整的浏览器会增加运行开销,而不一定能增加信息量。如果页面在 JavaScript 执行后才构建其有用内容,则可能需要采用浏览器路径。交互式筛选器或客户端分页控件可以使这种区别变得明显。

不要仅凭站点的外观来判断。一个视觉上复杂的页面可能会在初始响应中包含其记录,而一个界面朴素的页面可能会在稍后才填充所有内容。请检查实际响应和渲染状态中是否包含任务所需的字段。

浏览器还会改变文档的寻址方式。嵌入式框架中的价格小部件并不仅仅是父文档中更深层的一个节点。 HTML 文档和浏览上下文模型 解释了为什么爬虫在从文档中抽取内容之前,必须先识别出包含其目标的文档。

请求身份决定处理内容

请求身份决定两个发现的链接是否代表相同的抓取工作单元。只有当身份规则与应用场景相匹配时,URL 去重才有帮助。

一个跟踪参数可能不会改变产品页面,而语言或分页参数则可能选择不同的内容。移除所有查询字符串可能会把本应不同的结果合并在一起。保留所有参数又可能导致重复的工作。明确哪些 URL 组件对目标具有意义,并使用具有代表性的链接来测试该规则。

请求的标识与记录的标识也不相同。一个目录页可能包含许多产品;一个产品可能出现在多个目录页上。仅对页面请求进行去重本身无法保证得到每个产品对应一条记录的数据集。

在来源提供稳定记录标识符时,请保留该标识符,以及来源 URL 和相关的集合上下文。如果来源缺乏可靠的标识符,请记录下游使用的匹配规则。猜测得到的相等规则可能会悄然合并不同的变体或具有相似标题的不同产品。

以有界目录抓取为例的设计

有界目录抓取从已批准的种子 URL 开始,并且只接受属于目标目录的链接。这是一个概念性设计示例,而不是一个已报告的执行过程或特定软件包的代码示例。

首先将发现页和详情页分开。使用分类处理器识别符合条件的详情链接和分页路径。使用详情处理器提取属于单个项目的字段。这种分离方式比起用一个将每个页面都视为可互换的处理器,更便于检查抓取范围和完整性。

在将发现的链接添加到队列之前,先指定主机和路径规则。导航菜单可能包含账户页面、外部推广以及不相关的部分。跟随每一个锚点会在没有获得操作人员相应决策的情况下改变任务范围。

根据数据集来定义“完成”。一条产品记录可能需要一个稳定的标识符和标题,并带有可为空的库存状态字段。缺失必填字段应产生一个明确的“不完整”结果。空类别是可以有效的,但前提是页面确实代表了预期的类别,并展示了一个已完成的空状态。

存储必须与结果的结构相匹配

Crawlee 将排队的工作与已存储的输出区分开来,因此一次爬取可以分别组织执行过程和结果。根据下游应用如何读取数据来选择存储方式。

数据集适用于一组记录的集合。键值存储适用于具名的数值或工件。两种存储选择都不决定记录是否正确。建立一个模式来覆盖字段名称、可为空的值、文本规范化,以及解释结果所需的来源上下文。

例如,没有货币单位的显示价格可能是含糊的。没有选定位置的库存状态可能具有误导性。一条记录可以在结构上是有效的 JSON,但仍然缺乏做出业务决策所需的上下文。保留这些输入,而不是试图在之后重建它们。

将工件与普通记录分开处理。截图可以解释缺失的字段,但也可能捕获与页面无关的信息。仅在需要时存储它们,保护访问权限,并使用与任务相匹配的保留策略。诊断性工件应与其解释的请求或记录有清晰的关联。

会话是爬取的输入

会话会影响爬虫看到的内容,即使目标 URL 保持不变。Cookies、账户状态、语言偏好和浏览器存储都可能改变返回的页面或渲染的应用。

“ HTTP cookie mechanism ”解释了服务器如何通过一种方式将请求与存储在浏览器中的状态关联起来。浏览器存储还有其他规则: Web Storage isolation and lifetime 区分以来源为作用域的数据与与标签页关联的会话存储。

对于本应相互独立的工作流,使用干净的状态。只有在连续性是明示需求时才复用已授权状态。在无关的任务之间共享一个可变的浏览器配置文件,可能会导致一个任务的输出依赖于另一个任务之前点击过的内容。

框架的会话功能、浏览器上下文、网站会话和远程浏览器分配不应被视为可以互换。说明清楚每个边界由哪个组件拥有。这使得可以判断故障是与队列处理、浏览器可用性、网站认证,还是页面状态变化有关。

如何评估一个 Crawlee 项目

从它组织的工作以及结果数据集中包含的证据来评估 Crawlee。一个小规模、有代表性的爬取,比统计有多少 URL 被放入队列更有参考价值。

检查要回答的问题
范围每个被接收的 URL 是否都属于已批准的任务?
执行路径是否需要 HTTP 解析或浏览器渲染?
请求标识是否保留了有意义的页面变体?
记录质量必填字段和来源上下文是否保留下来?
完成情况是否能够区分空结果、不完整结果和成功结果?

还要测试一个缺少可选数据的页面,以及一个超出接收范围的页面。这些情况可以揭示处理程序是否在执行预期策略。让错误结果在任务摘要中可见,而不是将没有记录视为“什么都没找到”的证据。

Scrapeless 在此架构中的位置

Scrapeless Agent Browser 属于浏览器执行层,而 Crawlee 属于爬取编排层。“ Agent Browser Puppeteer connection ”描述了一种受支持的客户端接口;它不应被理解为任意 Crawlee 浏览器池配置都可以不加改动地运行的证明。

“ Agent Browser platform ”在工作流需要托管的动态页面执行时是相关的。相关的讨论“ Crawlee for Python and crawl design ”可以帮助框定编排方面的选择。在将概念转化为方法或配置之前,请查阅特定语言的文档。

根据在选定最简单且足够的抓取路径之后仍需要完成的浏览器工作来评估 Scrapeless pricing 。这个定义并不声称已经执行或基准测试过 Crawlee 与 Scrapeless 的集成。

结论

Crawlee 将一组页面操作转变为一个有组织的爬取流程。从请求范围出发,围绕所需内容选择 HTTP 或浏览器执行,并将记录与页面请求解耦地定义。一个有用的爬取以可解释的数据和可见的不完整结果作为结束,而不是仅仅以队列被耗尽作为结束。

将浏览器概念付诸实践

使用 Scrapeless Agent Browser 探索一个已授权的浏览器工作流,然后验证任务所需的页面状态和输出。

立即注册即可获得 $5 in free credit — 无需信用卡.

Claim Your $5 Credit →

常见问题解答

Crawlee 是浏览器吗?

Crawlee 是一个爬取和抓取框架,而不是浏览器。它可以协调 HTTP 请求或基于浏览器的工作,而页面渲染和交互则由浏览器运行时来完成。

Crawlee 是否需要为每个 URL 进行浏览器渲染?

Crawlee 不需要为每个 URL 使用浏览器。当响应中已经包含所需内容时,使用 HTTP 路径;当需要脚本执行或交互时,使用浏览器路径。

请求去重是否会防止重复的数据记录?

请求去重并不会自动防止重复记录。同一条数据可能出现在多个页面上,而一个页面也可能包含多条数据。应当将记录标识与请求标识分开定义。

JavaScript 和 Python 的 API 可以互换使用吗?

不要假定 JavaScript 和 Python 的 API 可以互换使用。它们共享爬取的概念,但类、配置和支持的特性必须根据所使用语言和版本在文档中单独确认。

参考资料