ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Crawlee 类型系统全解:读懂 @crawlee/types 的公开 API 契约

Crawlee 类型系统全解:读懂 @crawlee/types 的公开 API 契约 Crawlee 类型系统全解读懂 crawlee/types 的公开 API 契约【免费下载链接】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 的网页抓取与浏览器自动化库其功能分散在多个子包中而crawlee/types正是这些子包之间共享的类型契约层HTTP 客户端接口、Cookie 体系、会话与代理、浏览器池、存储后端等关键抽象全部由它统一定义。本文以仓库中由 API Extractor 生成的公开 API 报告 docs/public-api/crawlee-types.api.md 为骨架结合 packages/types/src 下的源码逐一拆解每个类型的作用、字段语义与典型使用场景帮助你理解 Crawlee 各模块的对接边界并为自定义日志器、HTTP 客户端、浏览器池、会话池或存储后端提供可直接对照实现的最小契约。包的定位与导出结构crawlee/types在 packages/types/package.json 中的描述为 “Shared types for the crawlee projects”版本为 4.0.0是 Crawlee 4.x 系列的公共类型基础层。它的入口 packages/types/src/index.ts 只做了一件事——以export type *的形式重新导出 8 个类型模块export type * from ./status-message.js; export type * from ./storages.js; export type * from ./utility-types.js; export type * from ./browser.js; export type * from ./cookies.js; export type * from ./http-client.js; export type * from ./session.js; export type * from ./logger.js;这 8 个模块对应的源文件为模块文件主题packages/types/src/utility-types.ts基础工具类型Dictionary、AllowedHttpMethods 等packages/types/src/http-client.tsHTTP 请求/响应契约packages/types/src/cookies.tsCookie 与 CookieJar 契约packages/types/src/session.ts会话、代理信息、指纹packages/types/src/browser.ts浏览器池抽象packages/types/src/storages.ts数据集、键值存储、请求队列的后端契约packages/types/src/logger.ts日志器接口packages/types/src/status-message.ts状态消息选项值得注意的是该包的类型大多采用“结构化契约”设计例如CookieJar、SessionCookie在类型上兼容tough-cookie的对应类但crawlee/types自身并不依赖tough-cookie见 packages/types/src/cookies.ts 中的注释这正是依赖倒置思想的体现——提供方实现细节与消费方类型声明解耦。同样的公开 API 报告在 docs/public-api 目录下还有crawlee-core.api.md、crawlee-http-client.api.md、crawlee-browser-pool.api.md等共同构成 Crawlee 的完整 API 面。基础类型utility-typesDictionaryexport type DictionaryT any RecordPropertyKey, T;Dictionary是 Crawlee 中最常见的通用对象类型等价于RecordPropertyKey, T即任意键string、number、symbol到值T的映射。它被大量用于RequestSchema.headers、RequestSchema.userData、DatasetBackend的数据行类型、BrowserLikeResponse.headers()的返回值等场景是所有“KV 风格”数据的默认形态。AllowedHttpMethodsexport type AllowedHttpMethods | GET | HEAD | POST | PUT | DELETE | TRACE | OPTIONS | CONNECT | PATCH | get | head | post | put | delete | trace | options | connect | patch;AllowedHttpMethods同时接受大写与小写形式各 9 种标准 HTTP 方法用于HttpRequest.method、RequestSchema.method、UnprocessedRequest.method等字段保证请求方法与队列中请求的方法声明具有一致的受控取值。HTTP 客户端契约http-client该模块定义用户自定义 HTTP 客户端用于纯 HTTP 抓取及爬取过程中的附加请求必须满足的最小契约核心是BaseHttpClientexport interface BaseHttpClient { sendRequest(request: Request, options?: SendRequestOptions): PromiseResponse; }BaseHttpClient只有一个方法sendRequest接收标准Request对象与SendRequestOptions返回Response。Crawlee 内置的FetchHttpClientpackages/http-client/src/fetch-http-client.ts以及crawlee/got-scraping-client、crawlee/impit-client都是该接口的实现。仓库的 docs/guides/http-clients.mdx 和 docs/guides/impit-http-client/impit-http-client.mdx 分别介绍了如何用不同实现替换默认客户端。HttpRequest 与 HttpRequestOptionsHttpRequest描述一次 HTTP 请求的完整形态字段极其丰富见 packages/types/src/http-client.ts基础字段url: string | URL必填、method?: AllowedHttpMethods、headers?: Headers、body?: Readablenode:stream的可读流支持流式上传控制字段signal?: AbortSignal取消请求、timeout?: number超时毫秒数、encoding?: BufferEncoding响应编码、throwHttpErrors?: boolean是否对非 2xx 抛错、insecureHTTPParser?: boolean重定向字段followRedirect?: boolean | ((response: any) boolean)可传函数按响应动态决定是否跟随、maxRedirects?: numberCookie 与会话字段cookieJar?: CookieJar、sessionToken?: object代理与指纹字段proxyUrl?: string、useHeaderGenerator?: boolean、headerGeneratorOptions?: Recordstring, unknown、headerGenerator?: { getHeaders: (options: Recordstring, unknown) Recordstring, string }——后者用于生成浏览器风格的请求头是反反爬场景的关键钩子。HttpRequestOptions extends HttpRequest在此基础上追加了需要在使用方侧预先处理的便捷字段packages/types/src/http-client.tsexport interface HttpRequestOptions extends HttpRequest { searchParams?: SearchParams; // 查询字符串参数追加到 URL form?: Recordstring, string; // 表单体URL 编码 json?: unknown; // JSON 序列化请求体 username?: string; // Basic Auth 用户名 password?: string; // Basic Auth 密码 }其中SearchParams string | URLSearchParams | Recordstring, string | number | boolean | null | undefined非常灵活。SendRequestOptions、StreamOptions 与 RedirectHandlerSendRequestOptions是调用sendRequest时按“单次请求”覆盖的选项packages/types/src/http-client.tsexport interface SendRequestOptions { session?: ISession; cookieJar?: CookieJar; timeoutMillis?: number; // 毫秒级超时 signal?: AbortSignal; proxyUrl?: string; // 覆盖 session 中的代理手动设置可能干扰会话代理轮换 ignoreTlsErrors?: boolean; // true 时忽略 TLS 证书错误也由 session.proxyInfo.ignoreTlsErrors 触发MITM 代理场景 }StreamOptions extends SendRequestOptions追加了onRedirect?: RedirectHandler回调。RedirectHandler的签名是export type RedirectHandler ( redirectResponse: Response, updatedRequest: { url?: string | URL; headers: Headers }, ) void;它允许在重定向发生时检查响应并就地修改updatedRequest例如改写 URL 或注入头且重定向响应可通过response读取。Cookie 体系cookiesCookieCookie是浏览器风格 Cookie 的结构化描述packages/types/src/browser.ts字段包括name: string、value: string必填url?: string与 Cookie 关联的请求 URI会影响默认 domain/path/sourcePort/sourceSchemedomain?: string、path?: string、secure?: boolean、httpOnly?: booleansameSite?: Strict | Lax | None、sameParty?: boolean、priority?: Low | Medium | Highexpires?: number过期时间不设置即为会话级 CookiesourceScheme?: Unset | NonSecure | Secure、sourcePort?: number-1或1-65535-1表示未指定端口。CookieJar 与 SessionCookieCookieJar是 Cookie 存储容器的契约packages/types/src/cookies.tsexport interface CookieJar { setCookie(cookie: string | SessionCookie, url: string | URL, options?: CookieJarSetCookieOptions): PromiseSessionCookie | undefined; getCookies(url: string | URL, options?: CookieJarGetCookiesOptions): PromiseSessionCookie[]; getCookieString(url: string | URL, options?: CookieJarGetCookiesOptions): Promisestring; getSetCookieStrings(url: string | URL, options?: CookieJarGetCookiesOptions): Promisestring[] | undefined; serialize(): PromiseSerializedCookieJar; toJSON(): SerializedCookieJar | undefined; clone(): PromiseCookieJar; }SessionCookie则在结构上完整对齐tough-cookie的Cookie类包含key、value、domain、path、secure、httpOnly、expires: Date | Infinity | null、maxAge、hostOnly、sameSite等属性以及cookieString()、toString()、TTL(now?)、expiryTime(now?)、expiryDate(now?)、isPersistent()、canonicalizedDomain()、clone()、validate()、setExpires()、setMaxAge()等方法。由于采用了结构化类型兼容任何满足该形状的tough-cookieCookie 对象都可以直接使用。CookieJarGetCookiesOptions支持http、expire、allPaths、sameSiteContext: none | lax | strict、sortCookieJarSetCookieOptions支持loose、sameSiteContext、ignoreError、http、now。SerializedCookieJar是 CookieJar 的 JSON 序列化形态version: string、storeType: string | null、rejectPublicSuffixes: boolean、cookies: Recordstring, unknown[]并允许扩展任意键。这一设计让会话状态可以被持久化、跨进程迁移是 Crawlee 会话恢复能力的基础。会话与代理sessionProxyInfoProxyInfo描述当前请求使用的代理连接信息packages/types/src/session.ts在爬虫的requestHandler({ proxyInfo })中可直接获取export interface ProxyInfo { url: string; // 代理 URL username?: string; password: string; hostname: string; port: number | string; ignoreTlsErrors?: boolean; // true 表示代理可能拦截 HTTPS 流量客户端会关闭 TLS 证书校验 }ignoreTlsErrors默认false当其置为true时内置 HTTP 客户端与浏览器池会为该会话的请求关闭 TLS 证书校验常见于中间人代理。SessionFingerprintSessionFingerprint标识会话正在模拟的浏览器画像packages/types/src/session.tsexport interface SessionFingerprint { browser?: chrome | firefox | safari | edge; platform?: windows | macos | linux | android | ios; device?: desktop | mobile; }这些字段只是“意图提示”消费方如crawlee/browser-pool、crawlee/impit-client会据此派生完整的浏览器指纹或 TLS 模拟画像并自行缓存会话本身只保存只读意图。ISession 与 ISessionPoolISession将每个会话建模为“一个特定用户”——拥有自己的 CookiecookieJar、IP通过proxyInfo和可选的浏览器指纹packages/types/src/session.tsexport interface ISession { readonly id: string; cookieJar: CookieJar; proxyInfo?: ProxyInfo; fingerprint?: SessionFingerprint; isUsable(): boolean; // 未过期、未被封禁且未达到最大使用次数时为 true markGood(): void; // 会话使用成功后调用 retire(): void; // 标记会话被封禁如收到 4035XX 等外部因素应使用 markBad markBad(): void; // 增加使用次数与错误计数如超时 }ISessionPool则只有单一方法export interface ISessionPool { getSession(sessionId?: string): PromiseISession | undefined; }不带 id 时由池自行决策返回哪个可用会话必要时新建带 id 时返回对应会话若仍可用。无法提供可用会话时返回undefined。内置的SessionPool实现位于 packages/core/src/session_pool代理轮换策略见 packages/core/src/proxy_configuration.ts实战用法参考 docs/guides/session_management.mdx 与 docs/guides/proxy_management.mdx。浏览器管理browserIBrowserPoolPage unknown是任何传入浏览器爬虫browserPool选项的对象必须满足的最小契约packages/types/src/browser.tsexport interface IBrowserPoolPage unknown { newPage(options?: NewPageOptions): PromisePage; closePage(page: Page, options?: { error?: Error }): Promisevoid; extractPageState(page: Page): PromisePageState; injectPageState(page: Page, state: PageState): Promisevoid; }newPage打开新页面由池决定使用哪个浏览器必要时启动新的closePage调用方用完页面后归还options.error传入错误信息若为SessionError实现方应清理该会话关联的所有状态如销毁提供该页面的浏览器extractPageState/injectPageState页面状态提取与注入当前仅包含 Cookie用于把爬取会话的 Cookie 注入页面、以及把页面 Cookie 回写到会话生命周期destroy由池的所有者负责——爬虫不会销毁用户传入的池。PageState目前只有cookies: Cookie[]一个字段NewPageOptions支持id?: string自定义页面 ID缺省为随机串与session?: ISession。特别值得注意的是session的注入是尽力而为的池可能使用会话的代理、Cookie 或指纹配置页面但不同实现如useIncognitoPages配置支持的子集不同爬虫仍需负责确定性的会话初始化。基于该接口可以接入远程浏览器农场、自定义指纹固定策略的池等相关实战见 docs/guides/remote_browser.mdx。存储后端契约storages这是crawlee/types中体量最大、设计最精细的部分定义了 Crawlee 三种存储数据集、键值存储、请求队列的后端Backend抽象——即存储的字节传输层。StorageBackend工厂入口StorageBackend是后端工厂packages/types/src/storages.ts一个新存储后端需要实现 4 个类StorageBackend工厂DatasetBackend、KeyValueStoreBackend、RequestQueueBackend三个子后端。其核心方法export interface StorageBackend { createDatasetBackend(options?: StorageIdentifier): PromiseDatasetBackend; createKeyValueStoreBackend(options?: StorageIdentifier): PromiseKeyValueStoreBackend; createRequestQueueBackend(options?: StorageIdentifier): PromiseRequestQueueBackend; storageExists?(id: string, type: Dataset | KeyValueStore | RequestQueue): Promiseboolean; getStorageBackendCacheKey?(): string; purge?(): Promisevoid; teardown?(): Promisevoid; stats?: { rateLimitErrors: number[] }; }StorageIdentifier是判别联合类型用于按 id / name / alias 三种方式定位存储且至多提供其一packages/types/src/storages.tsexport type StorageIdentifier | { id: string; name?: never; alias?: never } // 按唯一 ID 打开已存在存储 | { id?: never; name: string; alias?: never } // 按全局名称打开或创建跨运行持久化 | { id?: never; name?: never; alias: string } // 按运行级别名打开或创建运行结束时清理 | { id?: never; name?: never; alias?: never }; // 打开默认存储语义细节名称default被保留解析到默认存储并在启动时清空别名存储同样在启动时清空除非禁用purgeOnStartgetStorageBackendCacheKey返回不透明键用于StorageInstanceManager按后端划分缓存分区。仓库中的内置实现包括 packages/fs-storage/src/file-system-storage.ts 与 packages/core/src/memory-storage/memory-storage.ts。DatasetBackend 与分页export interface DatasetBackendData extends Dictionary Dictionary { getMetadata(): PromiseDatasetInfo; drop(): Promisevoid; // 删除数据集及其全部数据 purge(): Promisevoid; // 清空数据但保留数据集 pushData(items: Data[]): Promisevoid; getData(options?: DatasetBackendListOptions): PromisePaginatedListData; }DatasetBackendListOptions提供desc?、limit?、offset?。PaginatedListData自描述分页结果packages/types/src/storages.tsexport interface PaginatedListData { total: number; // 数据集条目总数 count: number; // 本页返回条数 offset: number; // 本页起始位置 limit: number; // 请求的最大条数 desc?: boolean; // 是否降序 items: Data[]; }前端如Dataset门面据offset items.length total即可判断是否到末尾。DatasetInfo包含id、name?、createdAt、modifiedAt、accessedAt、itemCount。KeyValueStoreBackend 与游标分页键值后端强调“字节传输”职责packages/types/src/storages.tsexport interface KeyValueStoreBackend { getMetadata(): PromiseKeyValueStoreInfo; drop(): Promisevoid; purge(): Promisevoid; getValue(key: string): PromiseKeyValueStoreRecord | undefined; setValue(record: KeyValueStoreInputRecord): Promisevoid; deleteValue(key: string): Promisevoid; listKeys(options?: KeyValueStoreListKeysOptions): PromiseKeyValueStoreListKeysResult; getPublicUrl(key: string): Promisestring | undefined; recordExists(key: string): Promiseboolean; }关键设计点KeyValueStoreRecord的值永远是原始字节Buffer | ArrayBuffer后端不做序列化/解析——解释由前端KeyValueStore依据contentType完成见 packages/types/src/storages.ts 注释KeyValueStoreInputRecord则接受宽松的KeyValueStoreRecordInputValueBuffer | ArrayBuffer | ArrayBufferView | string | NodeJS.ReadableStream | ReadableStream写入时前端已完成序列化getPublicUrl(key)不得检查记录是否存在——调用方会为尚未落盘如处于未提交事务缓冲中的记录合法地请求 URL存在性判断是recordExists的职责listKeys返回游标式分页结果KeyValueStoreListKeysResultitems、count、limit、exclusiveStartKey?、isTruncated: boolean、nextExclusiveStartKey?。与数据集的 offset 分页不同前端不应以items.length limit推断结束而应依据isTruncated并用nextExclusiveStartKey续页。RequestQueueBackend 与请求生命周期RequestQueueBackend是三种后端中最复杂的packages/types/src/storages.ts拥有请求簿记pending、in-progress、handled的全部职责分布式客户端之间的协调如在 Apify 平台上的请求锁是实现的内部关注点。核心方法addBatchOfRequests(requests: RequestSchema[], options?: RequestQueueOperationOptions): PromiseBatchAddRequestsResult——批量入队按uniqueKey去重重复项只在结果中报告而不重复入队fetchNextRequest(): PromiseUpdateRequestSchema | undefined——取出下一个待处理请求该请求被标记为 in-progress在reclaimRequest或markRequestAsHandled之前不会被再次返回返回undefined仅表示“当前没有待处理请求”不表示处理完成markRequestAsHandled(request)——将 in-progress 请求标记为已处理undefined返回是 no-op 而非错误该请求不是当前客户端处理的reclaimRequest(request, options?)——把失败请求放回队列以便后续重试forefront: true时放回队首isEmpty()vsisFinished()——isEmpty只看有没有可 fetch 的 pending 请求in-progress 的不算isFinished是强语义要求既无 pending 也无 in-progress 请求是判断爬取是否完成的构建块setExpectedRequestProcessingTimeSecs?(secs)——告知客户端一个请求预期被持有的时长消费方处理超时加 padding供基于锁的协调保持预留不锁的客户端可忽略getRequest(uniqueKey)、getMetadata()、drop()、purge()。请求本身的数据形态由RequestSchema描述packages/types/src/storages.tsexport interface RequestSchema { id?: string; url: string; // 必填 uniqueKey: string; // 必填去重键 method?: AllowedHttpMethods; payload?: string; noRetry?: boolean; retryCount?: number; errorMessages?: string[]; headers?: Dictionarystring; userData?: Dictionary; // 用户自定义数据 handledAt?: string; loadedUrl?: string; // 实际加载后的 URL可能经过重定向 }UpdateRequestSchema extends RequestSchema追加必填的id用于 fetch/update 流程。批处理结果BatchAddRequestsResult含processedRequests: ProcessedRequest[]与unprocessedRequests: UnprocessedRequest[]其中ProcessedRequest报告uniqueKey、requestId、wasAlreadyPresent、wasAlreadyHandledQueueOperationInfo是单项操作的同样信息。注意markRequestAsHandled对已处理请求是幂等的仍返回wasAlreadyHandled: true的操作信息。日志器loggerCrawleeLogger定义了 Crawlee 日志实现的完整接口packages/types/src/logger.ts允许用户注入 Winston、Pino 等自定义日志器同时保持与默认apify/log实现的兼容export interface CrawleeLogger { getOptions(): CrawleeLoggerOptions; setOptions(options: PartialCrawleeLoggerOptions): void; child(options: PartialCrawleeLoggerOptions): CrawleeLogger; error(message: string, data?: Recordstring, unknown, options?: LogOptions): void; exception(exception: Error, message: string, data?: Recordstring, unknown): void; softFail(message: string, data?: Recordstring, unknown, options?: LogOptions): void; warning(message: string, data?: Recordstring, unknown, options?: LogOptions): void; warningOnce(message: string): void; info(message: string, data?: Recordstring, unknown, options?: LogOptions): void; debug(message: string, data?: Recordstring, unknown, options?: LogOptions): void; perf(message: string, data?: Recordstring, unknown, options?: LogOptions): void; deprecated(message: string): void; logWithLevel(level: number, message: string, data?: Recordstring, unknown): void; }CrawleeLoggerOptions目前仅有prefix?: string | null每行日志前缀LogOptions仅有once?: boolean同文本只记一次warningOnce即warning(message, undefined, { once: true })的简写。deprecated用于对弃用特性输出一次警告perf用于性能追踪logWithLevel支持动态决定日志级别。完整的自定义实现示例Pino / Winston见 docs/guides/custom-logger/custom-logger.mdx、docs/guides/custom-logger/pino.ts 与 docs/guides/custom-logger/winston.ts。状态消息status-messageSetStatusMessageOptions用于BasicCrawler.setStatusMessagepackages/types/src/status-message.tsexport interface SetStatusMessageOptions { isStatusMessageTerminal?: boolean; // 是否为本次运行的最终状态消息 level?: DEBUG | INFO | WARNING | ERROR; // 默认 DEBUG }状态消息并非存储关注点——爬虫通过事件系统EventType.STATUS_MESSAGE广播再由 Apify SDK 等集成转发到状态上报后端。谁在消费这些类型契约的落地通过全仓搜索from crawlee/types可以确认该类型包是 Crawlee 各核心子包共同的类型基础消费方包括coreRequest、SessionPool、存储门面、log.ts等大量模块basic-crawlerBasicCrawler本体与send-request.tsbrowser-crawler / browser-poolBrowserCrawler、BrowserPool、Playwright/Puppeteer 插件控制器cheerio-crawler等各抓取器实现。这意味着当你在package.json中看到这些包声明了对crawlee/types的依赖时它们依赖的正是上文拆解的这一整套契约。对于想要深度定制的开发者最实用的方式是直接实现这里的接口自定义日志器 → 实现CrawleeLogger自定义 HTTP 客户端 → 实现BaseHttpClient自定义浏览器页供应策略 → 实现IBrowserPool自定义会话管理 → 实现ISessionPool自定义存储后端 → 同时实现StorageBackend 三个子 Backend。总结crawlee/types是 Crawlee 各子包之间的类型契约层本文基于 docs/public-api/crawlee-types.api.md 与其源码 packages/types/src 全面梳理了 8 个类型模块从Dictionary、AllowedHttpMethods等基础类型到 HTTP 客户端、Cookie 体系、会话与代理、浏览器池、三类存储后端、日志器与状态消息接口。理解这套契约既能帮你读懂 Crawlee 各模块之间的对接边界例如前端KeyValueStore负责序列化解析、后端只做字节传输的分层设计也能让你以最小成本接入自定义实现将 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),仅供参考
返回列表