Nstproxy 现已升级为 Nstdata。了解此次变化。
周一至周五 09:00 - 18:00(UTC+08:00) 公司地址
19H MAXGRAND PLAZA NO.3 TAI YAU STREET SAN PO KONG, KOWLOON HONG KONG ©2026 NST LABS TECH LTD. 保留所有权利。
Crawlee for Python: 实用抓取工作流程
Ivy Lin Community & Content Lead
Crawlee for Python: A Practical Guide to Web Scraping Workflows TL;DR
Crawlee for Python 是一个爬虫工作流框架。 它管理请求、队列、处理程序和数据集,围绕您的提取代码;它不仅仅是一个解析器或浏览器驱动程序。
从静态或服务器渲染页面的 HTTP 爬虫开始。 选择 BeautifulSoupCrawler 或 ParselCrawler;只有在内容确实需要浏览器渲染时才转向 PlaywrightCrawler。
当前官方 Python 文档为 1.11 版,要求使用 Python 3.10 或更新版本。 固定您验证的版本,特别是在升级存储或 HTTP 客户端行为时。
在首次运行时使用页面上限和允许列表域。 Crawlee 去重排队的 URL,但您仍然需要定义范围,仅提取授权数据,并测量完整性。
什么是 Crawlee for Python?
Crawlee for Python 是一个用于构建网络爬虫和数据提取工作流的开源框架。爬虫从 URL 开始,通过队列发送每个请求,为每个页面调用处理程序,并将提取的记录存储在数据集中。这为爬取编排提供了项目结构,而原始的 requests.get() 调用并不提供。如果您更喜欢用于允许的 URL 和站点收集的托管服务,Nstdata Crawl 是另一个选项;它并不取代 Crawlee 的自定义处理程序或特定于应用的 API 逻辑。
实际区别是:
请求 + Beautiful Soup: 你控制每个请求并解析 HTML。适合小型固定任务。
Crawlee: 您定义如何处理每个请求,而框架管理爬虫队列、重复请求、处理程序和存储。
Playwright: 您自动化浏览器。它可以渲染 JavaScript,但本身并不提供完整的爬虫工作流。
当前的 Crawlee Python 快速入门 列出了三个爬虫类:BeautifulSoupCrawler、ParselCrawler 和 PlaywrightCrawler。HTTP 爬虫不渲染 JavaScript;Playwright 爬虫控制无头浏览器。
Crawlee for Python vs Scrapy vs Playwright
工具 主要角色 请求队列和爬虫工作流 JavaScript 渲染 数据存储 适合人群
Crawlee for Python Python 爬虫框架 内置请求队列、处理程序、路由和存储 是,通过 PlaywrightCrawler 数据集和键值存储 希望实现受管理爬虫循环和 HTTP 到浏览器选择的 Python 团队
Scrapy 完整的 Python 爬虫框架 内置调度器、下载器、中间件和管道 本身不支持;需要时添加浏览器集成 项目管道和馈送 更大、更高度定制的爬虫项目,具有既定的 Scrapy 堆栈
Playwright 浏览器自动化库 本身没有通用的爬虫队列或数据集 是 您的应用程序代码 需要渲染或交互的授权内容的浏览器测试和页面
请求 + Beautiful Soup HTTP 客户端加 HTML 解析器 本身没有爬虫队列 否 您的应用程序代码 一些已知的 URL 或简单的 API/页面解析器
一个常见的错误是将 Crawlee 和 Playwright 进行比较,仿佛它们解决的是同一层次。Crawlee 可以将 Playwright 用作其浏览器引擎;单独使用 Playwright 会将 URL 发现、去重、作业限制、输出和重启行为留给您的应用程序。请参阅 Scrapy 蜘蛛文档 和 Playwright for Python 文档 以了解这些工具的边界。
Crawlee for Python 的工作原理 起始 URL → 请求队列 → 爬虫 + 路由器 → 请求处理程序 → 数据集
爬虫: 选择一个 HTTP 或浏览器支持的实现并运行作业。
请求 / 请求队列: 代表要访问的页面,并保持工作列表。Crawlee 默认使用 URL 派生的唯一键去重请求。
路由器和处理程序: 决定如何处理请求。对于第一个爬虫,一个单一的默认处理程序就足够;标签和路由处理程序帮助后来分离列出页面和详细页面。
数据集: 存储结构化记录。键值存储对于文件、屏幕截图或状态等工件是有用的。
HTTP 爬虫与浏览器爬虫 当服务器在 HTML 响应中返回数据时请使用 HTTP 爬虫。它避免了启动浏览器的开销,通常也更容易部署。当页面需要客户端渲染以暴露您被允许收集的内容时,请使用 PlaywrightCrawler。
在移动到浏览器之前,检查页面的初始响应并检查其数据是否以 HTML 或文档化的 API 形式存在。浏览器渲染增加了 CPU 和内存、浏览器二进制文件、较长的页面加载时间以及更多的故障点。这不是绕过访问控制或 CAPTCHA 挑战的方法。
请求队列、路由和数据集 当页面链接到更多页面,或当一个作业以已知列表开始但在运行时发现额外工作时,队列是有用的。请求处理程序可以提取一个记录并将下一个允许的链接加入队列。队列处理 URL 重复;您的代码仍然需要定义哪些页面在范围内,什么 qualifies 作为有效记录。
对于电子商务目录,列表处理程序可以提取产品卡并将单个下页链接加入队列。如果项目需要比列表提供的更多字段,则可以使用单独的详细处理程序来处理产品 URL。保持列表页面和详细页面模式明确,以便不将空的列表记录误认为是产品。
先决条件和安装 Crawlee for Python 目前需要 Python 3.10 或更新版本。快速启动安装为:
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install 'crawlee[all]'
对于带有浏览器的爬虫,请按文档中所述安装 Playwright 浏览器依赖项:
在锁定文件中固定依赖项,以便进行可重现的部署。当前文档版本为 1.11;Crawlee 1.0 升级指南描述了存储和默认 HTTP 客户端的更改,因此在重大升级后不要假设旧的代码示例的行为完全相同。
步骤 1:构建您的第一个 Crawlee Python 爬虫 此示例使用 Books to Scrape,一个演示目录。它从列表页面读取产品卡,仅跟随“下一页”链接,将爬行限制为三次请求,并将默认数据集导出为 CSV。在针对旨在测试的网站或您有权爬行的网站上运行示例。
配置爬虫和起始 URL 将以下内容保存为 books_catalog.py:
import asyncio
from crawlee . crawlers import BeautifulSoupCrawler , BeautifulSoupCrawlingContext
async def main ( ) - > None :
crawler = BeautifulSoupCrawler ( max_requests_per_crawl = 3 )
@crawler . router . default_handler
async def handle_page ( context : BeautifulSoupCrawlingContext ) - > None :
soup = context . soup
for card in soup . select ( "article.product_pod" ) :
title_link = card . select_one ( "h3 a" )
price = card . select_one ( ".price_color" )
availability = card . select_one ( ".availability" )
if title_link is None :
continue
await context . push_data (
{
"source_url" : context . request . url ,
"title" : title_link . get ( "title" ) or title_link . get_text ( strip = True ) ,
"product_url" : title_link . get ( "href" ) ,
"price_text" : price . get_text ( strip = True ) if price else None ,
"availability_text" : availability . get_text ( " " , strip = True )
if availability
else None ,
}
)
# Follow the listing's next-page link only; stay on the same hostname.
await context . enqueue_links ( selector = "li.next a" )
await crawler . run ( [ "https://books.toscrape.com/" ] )
await crawler . export_data ( path = "books.csv" )
if __name__ == "__main__" :
asyncio . run ( main ( ) )
请求上限故意使示例较小。对于真实项目,请设置与您有权限收集的范围匹配的页面或请求预算,并记录每个请求为何被接受。
提取数据并保存结果 每次调用 context.push_data() 都会向默认数据集添加一条记录。导出步骤将该数据集写入 CSV 文件。一个代表性行具有以下格式:
{
"source_url" : "https://books.toscrape.com/" ,
"title" : "A Light in the Attic" ,
"product_url" : "catalogue/a-light-in-the-attic_1000/index.html" ,
"price_text" : "£51.77" ,
"availability_text" : "In stock"
}
确切的当前值可能会在实时网站上发生变化;该代码片段显示字段,而不是承诺捕获的结果。每条记录都要保留源 URL。对于生产环境,请使用 urljoin() 规范化相对链接,存储爬虫时间戳,并验证每个产品是否具有下游作业所需的字段。
步骤 2:使用请求队列爬取多个页面 示例已经使用了Crawlee的隐式请求队列:crawler.run() 添加了起始URL,处理程序将下一个页面加入队列。当一个网站有许多已知的URL时,使用 crawler.run(urls) 或队列API来种子作业。Crawlee的官方介绍解释了 请求队列和链接发现 的工作原理。
发现和加入链接 默认情况下,context.enqueue_links() 保持在同一主机名上;选择器缩小了考虑的锚点范围。对于文档网站,爬虫可能使用选择器例如 a.sidebar-link 和页面上限,然后应用包括/排除模式来处理部分内容。
在存储URL之前进行规范化。还要决定查询字符串是否标识不同的页面:过滤器和跟踪参数可能会创建许多显示相同内容的URL。队列去重有助于处理完全相同的URL变体,但无法推断出两个语义上不同的URL包含相同的文章。
为不同页面类型使用路由器 当列表页和详情页需要不同的选择器时,在加入URL时分配标签并注册单独的路由处理程序。这使得提取逻辑更易于阅读:
列表处理程序:收集卡片,然后加入详情链接。
详情处理程序:提取仅存在于产品页面的字段。
错误处理程序:记录失败的URL、状态和简短的错误类别。
一旦爬虫成长,不要将所有页面类型放入一个巨大的条件中。分离的处理程序可以更容易地将页面固定装置与正确的架构进行测试。
第3步:抓取JavaScript渲染的网站 当HTTP响应中缺少允许的页面内容,并且仅在客户端渲染后出现时,切换到 PlaywrightCrawler。官方快速入门展示了使用Playwright上下文的相同基本处理程序接口:
import asyncio
from crawlee . crawlers import PlaywrightCrawler , PlaywrightCrawlingContext
async def main ( ) - > None :
crawler = PlaywrightCrawler ( max_requests_per_crawl = 5 )
@crawler . router . default_handler
async def handle_page ( context : PlaywrightCrawlingContext ) - > None :
title = await context . page . title ( )
await context . push_data (
{
"url" : context . request . url ,
"title" : title ,
}
)
await crawler . run ( [ "https://example.com/" ] )
if __name__ == "__main__" :
asyncio . run ( main ( ) )
这说明了浏览器爬虫API;它不能保证动态目标是可访问的。如果您自己的应用程序在已知选择器出现后渲染,请在特定于网站的处理程序中等待该选择器并设置超时。在可用的明确就绪条件下,避免固定的长时间睡眠。不要使用浏览器自动化来击败挑战或访问限制。
第4步:清理和验证提取的数据 爬虫可以在生成不完整记录的情况下成功完成。添加检查,在必需字段缺失时使作业失败或将记录路由到审查数据集:
需要一个稳定的标识符或来源URL。
拒绝没有标题的产品记录;如果页面未提供可保持价格可为空。
在单独的转换步骤中规范化空格、货币和相对URL。
根据商业关键字(例如规范产品URL)去重,而不仅仅是标题。
保存原始或代表性的HTML固定装置用于解析器回归测试。
分别跟踪发现的URL、处理过的URL、有效记录和失败请求。
Crawlee的 存储指南 记录了数据集和键值存储。将大型工件保留在关系行之外;存储引用或对象键即可。
第5步:基准吞吐量和可靠性 不要根据三页教程的运行估计生产吞吐量。在同一台机器上基准测试相同的授权URL集,并记录:
测量 重要性 有效记录 / 请求页面 将提取质量与HTTP成功区分开 中位数和p95页面延迟 捕获慢速页面而不隐藏尾部 每分钟请求数 测量在所选并发下的吞吐量 CPU和峰值内存 浏览器爬虫的资源配置可能不同 重试和失败计数 揭示脆弱的目标或配置问题 输出字节和存储增长 对于长时间运行或工件较重的作业很重要
运行一个小型试点,手动检查样本,然后逐渐增加数量。在转向计划执行前,设置最大请求计数、每域并发和作业超时。
第6步:部署Crawlee Python作业 对于小型定时 HTTP 爬虫,打包 Python 环境和存储输出,然后从容器或任务调度器运行脚本。基于浏览器的运行还需要兼容的浏览器二进制文件和系统依赖项;将它们包含在图像中,并测试确切的部署基础镜像。
计划处理重启和幂等性。给每次运行一个 ID,保留源 URL 和时间戳,并确保下游写入是安全可重复的。如果爬虫在崩溃后必须从持久化队列恢复,请用您打算部署的存储配置测试该行为,而不是假设本地运行证明云持久性。
何时使用 Python 的 Crawlee 与托管爬虫 API 当您需要自定义提取逻辑、想要控制调度和存储,并能够自己操作爬虫时,Crawlee 是一个很好的选择。托管爬虫 API 可以减少浏览器基础设施的工作并返回标准化的页面内容,但您仍然拥有爬虫策略、数据验证和下游处理。
Nstdata Crawl 描述了具有可配置页面限制的 URL 或站点级爬虫以及 Markdown 和 HTML 等输出。当应用程序需要页面内容而不是自定义爬虫代码库时,它非常有用。它并不是适用于每个任务的合适工具:当需要自定义控制或自托管时使用 Crawlee;当减少浏览器和爬虫基础设施操作更有价值时使用托管服务。相关的 Nstdata 指南涵盖了 在 Python 中抓取 JavaScript 渲染的页面 、动态网站的无头抓取 和 自动化数据收集 。
结论 Python 的 Crawlee 为 Python 项目提供了可重用的爬虫循环:请求进入队列,处理程序提取记录,数据集存储输出。从 HTTP 爬虫开始,明确允许的 URL 范围,只有在需要渲染时才添加 Playwright。页面限制和数据质量检查比一个悄无声息存储不完整行的大型爬虫更有用。
体验 Nstdata — 立即开始您的免费试用 如果您更倾向于一个托管服务进行允许的 URL 和站点收集,请在概念证明之前查看 Nstdata Crawl 的文档输入和输出。
常见问题 问:Crawlee for Python 免费吗?
Crawlee 是开源的,其文档描述它为免费。您仍需为您操作的计算、浏览器运行时、存储和基础设施付费。
问:Crawlee 可以渲染 JavaScript 吗?
是的。Python 的 Crawlee 包括 PlaywrightCrawler 用于基于浏览器的页面。BeautifulSoupCrawler 和 ParselCrawler 使用 HTTP 响应并不渲染 JavaScript。
这取决于项目。Crawlee 提供与 HTTP 到 Playwright 爬虫选择结合的集成队列、处理程序和存储工作流;Scrapy 是一个成熟的框架,拥有自己的调度器、中间件和管道。比较您的团队已经操作的集成。
问:Crawlee 是否会自动避免重复的 URL?
默认情况下,它的请求队列使用基于 URL 派生的唯一密钥对请求进行去重。您仍然应该对 URL 进行标准化,并根据您的应用程序所需的业务标识符去重记录。
快速入门模式在本地存储的一个数据集下存储记录。爬虫 API 还提供导出方法,例如 crawler.export_data(path="books.csv"),支持已安装版本支持的格式。
Ivy Lin
Oct. 19th 2026
支持 JavaScript 渲染,成功率达 99.8%
将任意网站转换为 Markdown、HTML、JSON、链接、PDF 等格式,无需管理爬取基础设施。 开始免费爬取 →