Crawlee 版本演进全解析:从 Apify SDK 到 v3.18 的核心变更与技术脉络
【免费下载链接】crawleeCrawlee—A web scraping and browser automation library for Node.js to build reliable crawlers. In JavaScript and TypeScript. Extract data for AI, LLMs, RAG, or GPTs. Download HTML, PDF, JPG, PNG, and other files from websites. Works with Puppeteer, Playwright, Cheerio, JSDOM, and raw HTTP. Both headful and headless mode. With proxy rotation.项目地址: https://gitcode.com/GitHub_Trending/cr/crawlee
Crawlee 是面向 Node.js 的 Web 爬取与浏览器自动化库,支持 Cheerio、JSDOM、LinkeDOM、Puppeteer、Playwright 与原生 HTTP 等多种执行环境。本篇基于仓库根目录的 CHANGELOG.md(记录了 v2.0.0 至 v3.18.1 的完整变更历史)展开,梳理 Crawlee 从 Apify SDK 中独立、完成 v3 大版本重构,再到后续持续迭代的演进脉络。读者将理解 Crawlee 的包体系设计、关键 API 的命名与语义变化、请求队列/链接入队/会话代理等核心机制的演进,以及如何结合 MIGRATIONS.md 与 docs/upgrading/ 目录完成版本升级。
一、项目背景:Crawlee 与 Apify SDK 的分家
Crawlee 是 Apify SDK(apify包)在爬取与浏览器自动化方向上的"精神继承者"。正如 CHANGELOG 在 v3.0.0 一节中说明的:v3 之前,apify包同时包含爬取工具与 Apify 平台辅助方法;v3 起将整个项目拆分为两部分:
- Crawlee:新的 Web 爬取库,以
crawlee包在 NPM 发布; - Apify SDK:Apify 平台辅助工具,以
apify包发布。
拆分后,Crawlee 以@crawlee命名空间发布多个子包。从当前仓库 packages/ 目录可以确认这套体系至今仍在沿用,并且已经进一步细化为:
| 包名 | 职责 |
|---|---|
@crawlee/core | 所有爬虫实现的基础,包含Request、RequestQueue、RequestList、Dataset等核心类 |
@crawlee/basic | 导出BasicCrawler(即 packages/basic-crawler) |
@crawlee/cheerio | 导出CheerioCrawler(packages/cheerio-crawler) |
@crawlee/browser | 导出BrowserCrawler,是@crawlee/playwright与@crawlee/puppeteer的基类 |
@crawlee/playwright/@crawlee/puppeteer | 导出PlaywrightCrawler/PuppeteerCrawler |
@crawlee/jsdom/@crawlee/linkedom | 导出JSDOMCrawler/LinkeDOMCrawler |
@crawlee/http | 导出HttpCrawler(packages/http-crawler) |
@crawlee/memory-storage/@crawlee/fs-storage | 存储实现(packages/fs-storage) |
@crawlee/browser-pool | 浏览器池(packages/browser-pool) |
@crawlee/utils | 工具方法(packages/utils) |
@crawlee/types | 主要存放StorageClient相关 TS 接口 |
@crawlee/stagehand | AI 驱动的浏览器自动化(v3.16 新增,packages/stagehand-crawler) |
@crawlee/otel | OpenTelemetry 可观测性集成(packages/otel) |
各包之间相互扩展并重导出,因此只需安装你实际使用的那个包即可。例如安装
@crawlee/playwright会自动带上@crawlee/browser,进而带上@crawlee/basic与@crawlee/core。同时crawlee元包(packages/crawlee)会重导出大多数@crawlee/*内容,方便一站式使用。
值得注意的是:当前仓库 lerna.json 中的发布版本为3.18.1,而各子包 package.json 中已标记为4.0.0,说明仓库正处在 v4 开发分支上;CHANGELOG 记录的最新正式版本是 2026-08-12 发布的v3.18.1。
二、v3.0 里程碑:一次彻底的重构
v3.0.0(2022-07-13)是 CHANGELOG 中篇幅最大、信息量最高的一节,它实质上是一份完整的"从 v2 迁移到 v3"指南,以下要点必须掌握。
2.1 安装方式
v3 时代@crawlee/*包尚未标记为latest,需要从next分发标签安装:
npm install crawlee@next # 仅需 Cheerio 支持时 npm install @crawlee/cheerio@next # 使用 Playwright / Puppeteer 时需显式安装浏览器驱动 npm install crawlee@next playwright # 或 npm install @crawlee/playwright@next playwright这一"显式安装浏览器依赖"的设计一直延续到今天:库本身不捆绑 Playwright/Puppeteer 版本,由使用者自行控制。
2.2 全量 TypeScript 支持
Crawlee 与 Apify SDK 均为完全 TypeScript 重写,类型随包发布。CHANGELOG 推荐使用@apify/tsconfig预设,并给出完整配置示例:
{ "extends": "@apify/tsconfig", "compilerOptions": { "module": "ES2022", "target": "ES2022", "outDir": "dist", "lib": ["DOM"] }, "include": ["./src/**/*"] }注意module/target需为ES2022及以上以支持顶层 await;noImplicitAny默认开启,初期开发可能需临时关闭。
2.3 Docker 多阶段构建
CHANGELOG 给出了推荐的 Dockerfile 模式:先用带开发依赖的基础镜像构建 TypeScript,再拷贝产物到仅含生产依赖的最终镜像,避免 TypeScript 等开发依赖进入运行镜像。
2.4 浏览器指纹替代 stealth
v2 中 Puppeteer 爬虫有一个"魔法般"的stealth选项,v3 将其替换为动态生成的浏览器指纹。若想关闭动态指纹,通过browserPoolOptions设置:
const crawler = new PlaywrightCrawler({ browserPoolOptions: { useFingerprints: false, }, });v3.0 还说明指纹缓存选项从useFingerprintPerProxyCache更名为useFingerprintCache(缓存不再绑定代理 URL,而是绑定会话)。对应实现位于 packages/browser-pool/src/fingerprinting/。
2.5 会话 Cookie 方法重命名
session.getPuppeteerCookies()/session.setPuppeteerCookies()更名为session.getCookies()/session.setCookies(),因为该方法适用于所有爬虫而不仅是 Puppeteer。相关实现见 packages/core/src/session_pool/session.ts。
2.6 存储:memory-storage 与自动清理
- v3 默认使用
@crawlee/memory-storage(内存存储 + 落盘 dump,尊重 KVS 中已有的INPUT.json),替代基于 SQLite 的@apify/storage-local; - 在 Apify 平台上运行时,通过
Actor.init/Actor.main自动切换到ApifyClient; - 本地运行默认自动清理存储(purge),可通过
Actor.init({ purge: false })关闭;--purge参数不再是必须的。
当前仓库中存储相关实现分布在 packages/core/src/storages/(抽象与核心逻辑)与 packages/fs-storage(文件系统实现)。
2.7 爬虫选项与上下文接口重命名
v3 统一了命名规范,旧名仍被支持(但不在 TS 层暴露):
| 旧名称 | 新名称 |
|---|---|
handleRequestFunction/handlePageFunction | requestHandler |
handleRequestTimeoutSecs/handlePageTimeoutSecs | requestHandlerTimeoutSecs |
requestTimeoutSecs | navigationTimeoutSecs |
handleFailedRequestFunction | failedRequestHandler |
上下文接口同步更名:CheerioHandlePageInputs→CheerioCrawlingContext、PlaywrightHandlePageFunction→PlaywrightCrawlingContext、PuppeteerHandlePageFunction→PuppeteerCrawlingContext。
2.8 上下文感知的 enqueueLinks 与三种入队策略
enqueueLinks从Apify.utils迁移到爬取上下文(context aware),不再需要手动传入requestQueue、page或$。同时提供三种策略:
EnqueueStrategy.All('all'):匹配页面上发现的任何 URL;EnqueueStrategy.SameHostname('same-hostname'):仅匹配与基准 URL 相同子域的链接(默认);EnqueueStrategy.SameDomain('same-domain'):匹配相同域名的链接,例如基准 URL 为https://example.com时,https://wow.an.example.com也会被匹配。
无需任何参数即可调用enqueueLinks(),默认过滤同子域链接;还可用 glob 模式筛选:
const crawler = new PlaywrightCrawler({ async requestHandler({ enqueueLinks }) { await enqueueLinks({ globs: ['https://apify.com/*/*'], // 也可使用 regexps 与 pseudoUrls }); }, });后续版本持续增强该助手:exclude选项(v3.3)、所有变体支持forefront(v3.2)、SameOrigin策略与协议匹配放宽(v3.2)、enqueueLinksByClickingElements(v3.1,Playwright)、waitForAllRequestsToBeAdded(v3.10.4)等。当前实现位于 packages/core/src/enqueue_links/。
2.9 隐式 RequestQueue 与 crawler.addRequests()
所有爬虫现在通过crawler.getRequestQueue()自动获得RequestQueue实例(仍可显式传入,方法会尊重传入实例)。crawler.addRequests()则以 1000 个为一组批量入队:先入队首批 1000 个并立即 resolve,其余在后台继续,避免触发 API 限流:
// 首批 1000 个请求入队后即 resolve const result = await crawler.addRequests([/* 可以是数百万个 */]); // 如需等待全部入队完成 await result.waitForAllRequestsToBeAdded;从源码看,packages/basic-crawler/src/internals/basic-crawler.ts 中addRequests是隐式RequestQueue.addRequestsBatched()的别名;批量入队的底层实现在 packages/core/src/storages/batched_adds.ts 与 packages/core/src/storages/request_queue.ts。v3.10 还专门优化了crawler.addRequests()大批量入队性能,v3.18 则修复了addRequestsBatched重复提交已入队请求与重试上限问题。
2.10 requestAsBrowser 的移除与 sendRequest
v3 移除requestAsBrowser,改为直接使用got-scraping,并新增上下文助手context.sendRequest():
const crawler = new BasicCrawler({ async requestHandler({ sendRequest, log }) { const res = await sendRequest({ responseType: 'json' }); log.info('received body', res.body); }, });同时整理了一批选项迁移:payload→body/json;ignoreSslErrors→https.rejectUnauthorized(语义相反,默认false);useMobileVersion/languageCode/countryCode→headerGeneratorOptions;timeoutSecs→timeout.request(毫秒);throwOnHttpErrors→throwHttpErrors;decodeBody→decompress;abortFunction被取消方案取代。当前仓库对应的 HTTP 客户端实现见 packages/http-client、packages/got-scraping-client 与 packages/impit-client。
2.11 其他 v3 行为变化
- 浏览器池禁止混合插件:同一池中混用 Puppeteer 与 Playwright 插件将直接抛错;
- 跳过导航:可用
Request.skipNavigation+context.sendRequest()在浏览器外处理请求(对应示例 docs/examples/skip-navigation.mdx); - 日志:
crawlee默认导出log实例;上下文内提供带爬虫名前缀的log,请求处理器内应优先使用; - 自动保存状态:每个爬虫都有
crawler.useState(),返回可自动持久化的状态对象(persistState事件触发保存,值有缓存):
const crawler = new CheerioCrawler({ async requestHandler({ crawler }) { const state = await crawler.useState({ foo: [] as number[] }); state.foo.push(123); // 无需手动保存 }, });- Apify SDK 侧:平台辅助方法(
Actor.init/exit/main、getInput、pushData、openDataset等)归入apify包;事件系统由EventManager管理(packages/core/src/events/),Actor.on/off替代Apify.events.on; - 内部破坏性变更:
Request.handledAt改为 ISO 字符串;Request.inProgress/reclaimed改为Set;APIFY_MEMORY_MBYTES由CRAWLEE_AVAILABLE_MEMORY_RATIO取代;AutoscaledPool的部分选项上移至顶层配置等。
三、v3.1 → v3.18 版本时间线:关键新增特性
CHANGELOG 记录了 v3 后续约两年半的迭代,以下按主题提炼每个版本值得关注的能力(括号内为对应源码/文档位置)。
3.1 请求来源与队列体系
- v3.5.5:引入Request Queue v2(RQv2),此后 v3.10 将 RQv2 设为默认队列;v3.13 进一步简化其实现;v3.16 移除对
RequestQueueV1的弃用标记; - v3.10.2:支持从字符串加载 sitemap;
- v3.11.0:新增Sitemap 驱动的请求列表(
SitemapRequestList),v3.11.2 为其加入globs/regexps过滤与弹性加载,v3.13.3 支持周期性持久化状态;对应实现 packages/core/src/storages/sitemap_request_loader.ts; - v3.13.9:
addRequests系列接受(Async)Iterables; - v3.15.0:新增
TandemRequestProvider,支持RequestList与RequestQueue组合使用(packages/core/src/storages/request_manager_tandem.ts),对应指南 docs/guides/request_loaders.mdx。
3.2 入队与抓取控制
- v3.14.0:新增
maxCrawlDepth爬虫选项,限制抓取深度;v3.15.0 修复其与自定义transformRequestFunction的兼容,v3.18.1 修复 JSDOM/LinkeDOM 上下文中对其的尊重; - v3.13.2:新增
onSkippedRequest回调,用于报告因过滤条件被跳过的链接(v3.13.9 完善); - v3.13.8:不入队超过爬虫处理能力的链接数量;
- v3.18.0:
enqueueLinksByClickingElements允许任意clickOptions。
3.3 反检测与浏览器能力
- v3.13.0:Playwright 新增
handleCloudflareChallenge助手,v3.16 使其更可配置,v3.18.1 适配新的 Cloudflare 挑战标记; - v3.13.0:新增Camoufox 爬虫模板(packages/templates/templates/camoufox-ts/),v3.13.3 默认关闭其指纹;
- v3.6.1:Puppeteer 启用新的 headless 模式;v3.8.0 支持
puppeteer@v22,v3.18.0 支持puppeteer@25; - v3.9.1:新增
browserPerProxy浏览器启动选项; - v3.15.2:默认启用
systemInfoV2;v3.17 新增动态内存快照,v3.18 修复其 CPU tick 基线。
3.4 代理与会话
- v3.9.0:
ProxyConfiguration新增tieredProxyUrls(分层代理)与更好的newUrlFunction;v3.12.1 支持传入null关闭代理; - v3.5.0:新增
sameDomainDelay、closeCookieModals上下文助手、代理错误自动退休会话;v3.3.1 修复会话轮换问题; - v3.1.1:
concurrency选项覆盖顺序修复、会话标记为 bad 等;相关实现见 packages/core/src/session_pool/ 与 packages/core/src/proxy_configuration.ts。
3.5 爬虫家族扩张
- v3.0.3:新增HttpCrawler与JSDOMCrawler;
- v3.4.0:新增LinkeDOMCrawler(packages/linkedom-crawler);
- v3.8.0:新增AdaptivePlaywrightCrawler(自适应渲染类型检测的爬虫),后续持续完善持久化与结果比较器(v3.13.5、v3.16.0);
- v3.10.0:新增FileDownload文件下载器,v3.13.3 向
streamHandler传入response,v3.17 新增abortDownload助手(对应示例 docs/examples/file_download.mdx); - v3.16.0:新增
@crawlee/stagehand,支持 AI 驱动的浏览器自动化(docs/guides/stagehand_crawler.mdx)。
3.6 存储、统计与可观测性
- v3.3.0:新增
setStatusMessage基础支持;v3.5.0 支持配置自动状态消息;v3.18.0 确保终止状态消息可靠送达; - v3.7.0:新增 robots.txt 与 sitemap.xml 工具集(packages/utils/src/internals/),v3.13.1 将
RobotsFile更名为RobotsTxtFile,v3.15.3 支持自定义userAgent; - v3.10.0:实现ErrorSnapshotter错误上下文快照(packages/core/src/error_snapshotter.ts)与 RQv2 默认化;
- v3.12.0:允许使用其他 HTTP 客户端;v3.12.2 新增 impit 客户端,v3.13.0 使用原生 impit 流式传输;当前模板默认使用
ImpitHttpClient(v3.17); - v3.13.8 / v3.15.0:Dataset 新增
collectAllKeys全量 CSV 导出选项;crawler.exportData()助手(v3.6.0)。
四、源码级印证:关键机制在今天仓库中的样子
以 packages/basic-crawler/src/internals/basic-crawler.ts 为入口,可以印证 CHANGELOG 中多项特性在 v4 分支上的延续:
skipNavigation、onSkippedRequest、sameDomainDelaySecs(默认 0,大于 0 时为每个站点建立独立节流时钟)、maxCrawlDepth、respectRobotsTxtFile(布尔或{ userAgent },默认false)均作为构造选项存在,与 CHANGELOG 中 v3.13.1/v3.13.2/v3.14.0/v3.15.3 的记载一一对应;useState()实现了匿名索引去重与共享状态告警,呼应 v3.0 的"自动保存爬虫状态";addRequests注释明确它是隐式RequestQueue.addRequestsBatched()的别名,对应 v3.4.2 引入的批量入队 API。
存储层面,packages/core/src/storages/ 中request_queue.ts(RQv2)、request_manager_tandem.ts(Tandem)、sitemap_request_loader.ts(SitemapRequestList)、batched_adds.ts(批量入队)等文件直接对应 CHANGELOG 中关于请求队列体系的一系列迭代。测试方面,test/core/ 下的request_manager_tandem.test.ts、sitemap_request_loader.test.ts、test/core/storages/ 下的request_queue.test.ts等用例为这些机制提供了可执行佐证。
五、升级路径与文档索引
- 各版本完整变更细节均记录在 CHANGELOG.md(当前最新记录 v3.18.1);
- 跨大版本升级指南位于 docs/upgrading/upgrading_v3.md 与 docs/upgrading/upgrading_v4.md;
- 仓库根目录 MIGRATIONS.md 提供整体迁移说明;
- 各子包也维护独立 CHANGELOG(如 packages/core/CHANGELOG.md、packages/browser-pool/CHANGELOG.md),便于聚焦单个模块的变更;
- 特性用法可参考 docs/guides/ 与 docs/examples/ 中的对应指南与示例。
结语
从 v2 到 v3 的拆分重构,到 v3.18 为止的持续打磨,Crawlee 的版本历史本身就是一部爬虫框架的工程进化史:包粒度更细、API 命名更统一、请求来源更多元(队列 v2、Sitemap、Tandem)、反检测手段更现代(指纹、Cloudflare 挑战处理、Camoufox)、爬虫类型更丰富(HTTP、JSDOM、LinkeDOM、Adaptive、Stagehand)。理解这份 CHANGELOG,等于同时理解了 Crawlee 的设计取舍与迁移路径,无论你是初次选型还是从旧版本升级,都能据此做出有依据的决策。
【免费下载链接】crawleeCrawlee—A web scraping and browser automation library for Node.js to build reliable crawlers. In JavaScript and TypeScript. Extract data for AI, LLMs, RAG, or GPTs. Download HTML, PDF, JPG, PNG, and other files from websites. Works with Puppeteer, Playwright, Cheerio, JSDOM, and raw HTTP. Both headful and headless mode. With proxy rotation.项目地址: https://gitcode.com/GitHub_Trending/cr/crawlee
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考