Crawlee 聚合包公开 API 全解析:从utils命名空间到 12 个子包的统一入口
【免费下载链接】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是 Crawlee 项目的聚合入口包(umbrella package),它将@crawlee/core、@crawlee/playwright、@crawlee/puppeteer、@crawlee/utils等全部子包的公开 API 汇于一处,并额外暴露一个内置的utils命名空间。本文以仓库中的公开 API 报告 crawlee.api.md 为骨架,结合 packages/crawlee/src/index.ts 及@crawlee/utils各工具源码,逐项拆解crawlee包到底导出什么、每个工具如何工作、以及这份 API 报告文件本身是怎样被生成和维护的。读完你将能准确判断"从crawlee能导入什么、该从哪个子包导入什么",并理解该仓库的公开 API 兼容性承诺机制。
crawlee包是什么:一份来自 package.json 的定位
从 packages/crawlee/package.json 可以看出,crawlee包自述为 "The scalable web crawling and scraping library for JavaScript/Node.js",版本为4.0.0,要求node >= 22.0.0,采用 ESM("type": "module")。关键信息如下:
- 它不实现任何爬虫逻辑,而是把
@crawlee/basic、@crawlee/browser、@crawlee/browser-pool、@crawlee/cheerio、@crawlee/core、@crawlee/fs-storage、@crawlee/http、@crawlee/jsdom、@crawlee/linkedom、@crawlee/playwright、@crawlee/puppeteer、@crawlee/utils全部作为workspace:*依赖引入并重新导出; playwright与puppeteer是可选 peer 依赖(peerDependenciesMeta中标记为optional),意味着你不装浏览器驱动也能使用 HTTP 类爬虫,只有在使用 Playwright/Puppeteer 爬虫时才需要安装对应浏览器库;bin指向./src/cli.ts,通过 src/cli.ts 中的import-local机制加载@crawlee/cli,提供npx crawlee脚手架命令,但 CLI 本身不参与公开 API 承诺(详见后文)。
也就是说,日常开发中import { ... } from 'crawlee'能拿到的所有东西,在类型层面都记录在这份 crawlee.api.md 报告中。
报告总览:crawlee公开表面只有两大部分
API Extractor 生成的报告结构非常简单清晰:
- 一个显式声明的
utils常量对象(8 个成员,均标注@public); - 12 条
export * from "@crawlee/..."全量转发声明。
实际源码 packages/crawlee/src/index.ts 与报告一一对应:前 17 行完成 12 个子包的全量转发,第 19–28 行定义utils对象。
export const utils = { puppeteer: puppeteerUtils, playwright: playwrightUtils, log, social, sleep, downloadListOfUrls, parseOpenGraph, extractMicrodata, };注意报告中的顺序(puppeteer、playwright、log、social、sleep、downloadListOfUrls、parseOpenGraph、extractMicrodata)与源码完全一致,因为这份.api.md就是由编译产物dist/index.d.ts机械生成的。
utils命名空间逐成员解析
utils的设计意图很明确:把高频的、与"爬虫运行时"解耦的通用工具函数收拢到一个命名空间下,避免@crawlee/utils的深层路径导入。下面结合@crawlee/utils源码逐一说明。
puppeteer/playwright:浏览器工具集
这两个成员分别引用@crawlee/puppeteer与@crawlee/playwright包的puppeteerUtils/playwrightUtils命名空间(见 packages/utils/src/index.ts 与 crawlee 入口源码的导入语句)。它们封装了与浏览器实例、页面生命周期、page.evaluate辅助等相关的实用函数,是编写 Playwright/Puppeteer 爬虫处理函数时的常用补充工具。由于浏览器工具集随浏览器子包演进,这里不逐一枚举其成员,以各子包公开 API 报告(如 crawlee-puppeteer.api.md、crawlee-playwright.api.md)为准。
log:全局日志实例
log直接引用@crawlee/core的Log实例。它贯穿整个 Crawlee 运行时——爬虫状态、请求重试、统计信息都会经由该实例输出。在自定义爬虫代码中可直接使用:
import { log } from 'crawlee'; log.info('开始抓取任务', { url: 'https://example.com' });social:社交媒体信息提取
social是@crawlee/utils中以命名空间方式导出的整组社交信息工具(源码见 packages/utils/src/internals/social.ts),内部通过export * as social from './internals/social.js'暴露(见 packages/utils/src/index.ts)。它提供两类能力:
邮箱与电话提取:
emailsFromText(text)/emailsFromUrls(urls):从纯文本或mailto:链接数组中提取邮箱地址。内部使用EMAIL_REGEX(精确单条匹配,/^...$/i形式)与EMAIL_REGEX_GLOBAL(批量匹配,/.../ig形式),两个正则都遵循 RFC 5321 的长度约束(local part 与域名标签分别限长{1,64}、{0,62}),源码注释明确说明这是为了避免在长输入上产生二次回溯(ReDoS);phonesFromText(text)/phonesFromUrls(urls):从文本或tel:/phone:/callto:链接中提取电话号码。源码内置了十余种常见号码格式模式,并做了两层过滤:少于 7 位数字的结果被丢弃(PHONE_MIN_DIGITS),形如2018-11-10的日期模式被排除(SKIP_PHONE_REGEXS)。phonesFromText的结果被归类为"不确定"(uncertain),因为纯文本号码误报率高。
社交平台正则(每平台一对精确/全局正则):
| 平台 | 精确匹配 | 批量匹配 |
|---|---|---|
LINKEDIN_REGEX | LINKEDIN_REGEX_GLOBAL | |
INSTAGRAM_REGEX | INSTAGRAM_REGEX_GLOBAL | |
| Twitter/X | TWITTER_REGEX | TWITTER_REGEX_GLOBAL |
FACEBOOK_REGEX | FACEBOOK_REGEX_GLOBAL | |
| YouTube | YOUTUBE_REGEX | YOUTUBE_REGEX_GLOBAL |
| TikTok | TIKTOK_REGEX | TIKTOK_REGEX_GLOBAL |
PINTEREST_REGEX | PINTEREST_REGEX_GLOBAL | |
| Discord | DISCORD_REGEX | DISCORD_REGEX_GLOBAL |
这些正则都使用负向后瞻/前瞻防止误匹配嵌入在单词中的 URL,且维护了"保留路径"黑名单(如 Twitter 的home、login、hashtag等,Facebook 的rsrc.php、groups等),避免把平台的功能页误判为用户主页。全局版本在遇到带子路径的 URL 时只截取基础主页部分。
综合入口parseHandlesFromHtml(html, data?):一次性从 HTML 文档中提取邮箱、电话与全部社交平台主页,返回SocialHandles结构(含emails、phones、phonesUncertain、linkedIns、twitters、instagrams、facebooks、youtubes、tiktoks、pinterests、discords字段)。实现上它先用 cheerio 解析文档:电话来自tel:链接(高置信度),邮箱来自mailto:链接加纯文本(保留重复并按字母序去重),社交 URL 则直接对原始 HTML 做全局正则匹配。可选的data参数会回填data.$(cheerio 对象)与data.text(纯文本),避免调用方二次解析。
sleep:毫秒级延时
sleep是极简的异步延时工具,源码见 packages/utils/src/internals/general.ts,底层直接复用node:timers/promises的setTimeout:
export async function sleep(millis?: number): Promise<void> { return setTimeout(millis ?? undefined); }用途很明确:在爬虫处理函数中放慢请求节奏、规避目标站点的反爬限制。若传入非正数或省略参数,Promise 会立即 resolve。示例:
import { sleep } from 'crawlee'; // 每次请求前休息 1.5 秒 await sleep(1500);同一文件还导出了两个 URL 匹配正则URL_NO_COMMAS_REGEX与URL_WITH_COMMAS_REGEX(后者额外支持 URL 路径/查询中的逗号,但可能破坏逗号分隔列表的解析),以及expandShadowRoots这类内部工具。
downloadListOfUrls:下载并解析 URL 列表
该函数用于"给定一个 URL,下载其内容并抽出其中所有链接",典型场景是抓取 CSV、纯文本种子列表。源码与参数校验见 packages/utils/src/internals/extract-urls.ts,支持选项如下:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url | string | 必填 | 待下载的资源地址 |
encoding | BufferEncoding | 'utf8' | 文件编码 |
urlRegExp | RegExp | URL_NO_COMMAS_REGEX | 自定义 URL 匹配正则,应为大小写不敏感且带 global 标志(如/something/gi) |
proxyUrl | string | 无 | 下载请求使用的代理 |
httpClient | BaseHttpClient | new FetchHttpClient() | 自定义 HTTP 客户端 |
实现细节值得一提:
- 内部通过 zod schema 做严格参数校验(
z.strictObject,非法参数会抛出ArgumentValidationError); - 对 Google 表格的分享链接做了自动修复:若 URL 匹配
docs.google.com/spreadsheets/d/...,会被改写为.../gviz/tq?tqx=out:csv以获取可下载的 CSV 数据; - 下载完成后用
TextDecoder按指定编码解码,再交给extractUrls按行切分、逐行用正则抽 URL。
parseOpenGraph:Open Graph 元数据解析
parseOpenGraph从页面 HTML(或已加载的 cheerio 对象)中解析 Open Graph 协议元数据,源码见 packages/utils/src/internals/open_graph_parser.ts。用法:
import { parseOpenGraph } from 'crawlee'; const og = await parseOpenGraph('<html><head><meta property="og:title" content="标题"/></head></html>'); // => { title: '标题' }实现要点:
- 内置一份
OPEN_GRAPH_PROPERTIES声明表,覆盖og:title、og:type、og:image(含url/secure_url/type/width/height/alt子属性)、og:url、og:audio、og:description、og:determiner、og:locale(含alternate)、og:site_name、og:video,以及不以og:开头的扩展属性族:video(video:actor、video:director、video:duration等)、music(专辑、曲目、音乐人等)、article(发布时间、作者、标签等)、book(作者、ISBN 等)、profile(姓名、用户名、性别等); - 同一属性出现多次(如多个
video:actor)时会保留为数组,单个值则返回字符串; - 带子属性的属性会组织成嵌套对象,原始值以
<outputName>Value键存放,例如og:image的裸值落在imageValue下; - 支持第二个参数
additionalProperties传入自定义的OpenGraphProperty声明以扩展解析范围。
extractMicrodata:schema.org 微数据解析
extractMicrodata按照 HTML 规范中的 microdata processing model。它接受原始 HTML 字符串或 cheerio 对象,返回顶层MicrodataItem数组,每个 item 包含:
type:itemtype属性的 tokens(如["https://schema.org/Product"]);id:itemid属性;properties:按itemprop名归组的属性值,值类型为字符串或嵌套的MicrodataItem,同名属性重复时以数组存储。
实现上遵循微数据的作用域规则:嵌套itemscope元素构成独立 item,其子树不再归属外层 item;itemref引用通过按需建立的id索引(Map<string, Element>)解析,源码注释说明大多数文档不会触发itemref查找,因此该索引采用惰性构建。文本值会被 trim 并折叠内部空白,URL 类属性原样返回而不做相对路径解析。
注意:
@crawlee/utils还导出htmlToText、extractUrls、EnqueueStrategy、robots、sitemap、expandShadowRoots等更多工具(见 packages/utils/src/index.ts),它们大多可通过@crawlee/utils子包直接导入;而crawlee聚合包只把上述 8 个高频成员收进utils命名空间。
12 个export *:聚合包背后的子包矩阵
报告第二部分的 12 条export *定义了crawlee对全部子包的转发,构成完整的爬虫能力栈:
| 子包 | 职责定位 |
|---|---|
@crawlee/core | 爬虫基类、自动伸缩(autoscaling)、请求/会话/存储管理等运行时核心 |
@crawlee/basic | 基于 HTTP 的基础爬虫抽象 |
@crawlee/browser | 浏览器类爬虫抽象层(无头/有头浏览器通用逻辑) |
@crawlee/http | 直接使用 HTTP 客户端的高性能爬虫 |
@crawlee/cheerio | 基于 Cheerio 的静态 HTML 解析爬虫 |
@crawlee/jsdom | 基于 JSDOM 的 DOM 爬虫 |
@crawlee/linkedom | 基于 linkedom 的轻量 DOM 爬虫 |
@crawlee/playwright | Playwright 驱动爬虫(含playwrightUtils) |
@crawlee/puppeteer | Puppeteer 驱动爬虫(含puppeteerUtils) |
@crawlee/browser-pool | 浏览器实例池、指纹与代理轮换 |
@crawlee/fs-storage | 基于文件系统的存储实现(数据集、键值存储、请求队列) |
@crawlee/utils | 通用工具(sleep、social、downloadListOfUrls等) |
这样,用户只需import { CheerioCrawler, Dataset, ... } from 'crawlee'即可获得完整能力,而无需关心各子包的边界。各子包的完整类型级接口可分别查阅 crawlee-core.api.md、crawlee-cheerio.api.md、crawlee-playwright.api.md 等同目录报告。
这份报告文件是怎么来的:API Extractor 工作流
crawlee.api.md顶部声明 "Do not edit this file. It is a report generated by API Extractor",它确实是机械生成的产物。维护流程记录在 docs/public-api/README.md:
- 生成:先
pnpm build构建所有包,再从每个包的dist/index.d.ts运行 API Extractor 生成报告。根目录package.json中对应脚本为pnpm api:extract(内部通过pnpm dlx github:apify/api-extractor-report执行); - 校验:CI 运行
pnpm api:check(等价于 extract 命令加--verify),一旦提交的报告与当前构建结果不一致即失败——这要么意味着 API 变更是有意的(提交更新后的报告,reviewer 通过 diff 审视公开表面变化),要么是无意的(需要修复源码); - 范围:报告采用 API Extractor 的
public变体,被标记为@internal(含@alpha/@beta与旧式@ignore)的符号会被剔除,只有@public表面进入报告;未打标签的符号按约定隐式视为 public(该代码库不使用显式@public标签); - 被遗忘的导出(forgotten exports):若某类型被公开 API 引用但入口文件从未导出它,报告会通过
includeForgottenExports将其纳入,并带显式横幅注释// Not exported by the entry point; reachable only as a referenced type.——其"形状"属于兼容性承诺范围,但名称不可导入,因此输出时不带export。报告会随后处理:裁剪掉仅被@internal成员引用而未能存活的声明与死导入,保证报告里不出现自身未声明的符号; - 排除清单:
@crawlee/cli与@crawlee/templates被刻意排除在报告之外,因为它们是工具型包(CLI 二进制与项目脚手架),不属于承诺向后兼容的可导入 API(排除列表在scripts/api-extractor/run.ts中维护); - 中间产物:
docs/public-api/temp/存放中间报告(含暂存的.public.api.md),已被 git-ignore。
这正是 crawlee.api.md 中// (No @packageDocumentation comment for this package)注释的由来——报告只反映类型级表面,不包含包级文档注释。
实践指南:如何正确使用crawlee聚合包
安装(任一子包均随聚合包可用,浏览器驱动按需选装):
npm install crawlee # 使用 Playwright 时再装: npm install crawlee playwright # 使用 Puppeteer 时再装: npm install crawlee puppeteer导入实践:
import { CheerioCrawler, // 来自 @crawlee/cheerio Dataset, // 来自 @crawlee/core / storages sleep, // utils 命名空间成员,亦可顶层导入 social, // utils 命名空间成员 utils, // 整个命名空间 } from 'crawlee'; // 用 social 从抓到的 HTML 里提取联系方式 const html = '<a href="mailto:hello@example.com">Contact</a>'; const handles = await social.parseHandlesFromHtml(html); // => { emails: ['hello@example.com'], phones: [], ... } // 用 sleep 控制请求节奏 await sleep(1000); // 用 downloadListOfUrls 把种子 URL 列表转成请求队列 const urls = await utils.downloadListOfUrls({ url: 'https://example.com/urls.txt' });类型校验:crawlee是纯 ESM 包("type": "module",exports指向./dist/index.js),要求 Node.js ≥ 22;在 CommonJS 项目中请使用动态import()或升级为 ESM 工程。
何时应该绕过聚合包:当你的项目只想使用@crawlee/utils中的某个工具(如robots、sitemap、EnqueueStrategy)时,直接安装并导入对应子包可减小依赖面;同时crawlee聚合包不会转发@crawlee/impit-client、@crawlee/http-client、@crawlee/otel、@crawlee/types等基础设施包的导出,这些需按需从各自包名导入。
小结
crawlee聚合包的公开 API 表面由两件事构成:一个 8 成员的utils命名空间(puppeteer、playwright、log、social、sleep、downloadListOfUrls、parseOpenGraph、extractMicrodata)和12 条子包全量转发。前者每个成员都能在 packages/utils 找到精确实现,后者把 core、browser、cheerio、playwright、puppeteer、fs-storage 等能力统一到一个导入源。而 crawlee.api.md 本身,则是仓库用 API Extractor 把这份承诺固化成机器可校验契约的载体——任何对公开 API 的改动,都会被pnpm api:check拦截并要求同步更新报告,从而让"向后兼容"成为可审计、可 diff 的工程实践。
【免费下载链接】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),仅供参考