ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Crawlee HTTP 客户端公共 API 详解:BaseHttpClient、FetchHttpClient 与自定义请求管线

Crawlee HTTP 客户端公共 API 详解:BaseHttpClient、FetchHttpClient 与自定义请求管线 Crawlee HTTP 客户端公共 API 详解BaseHttpClient、FetchHttpClient 与自定义请求管线【免费下载链接】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/crawleeCrawlee 的crawlee/http-client包为纯 HTTP 爬取无需浏览器提供了一套统一的、基于标准fetch语义的请求层抽象上层爬虫通过BaseHttpClient.sendRequest()发起请求由具体实现原生FetchHttpClient、GotScrapingHttpClient、ImpitHttpClient等完成低层网络调用。本文以该包的公共 API 报告docs/public-api/crawlee-http-client.api.md为骨架逐类拆解其公开类型与类并结合源码说明重定向处理、Cookie 管理、代理与指纹注入的实现机制帮助你理解并自定义 Crawlee 的 HTTP 请求管线。一、包概览面向 HTTP 爬取的统一请求抽象crawlee/http-client的公共 API 由四个部分组成全部集中在 packages/http-client/src/index.ts 中导出公开符号类型作用BaseHttpClient抽象类定义请求管线的骨架实现sendRequest()把重定向、Cookie、代理等横切逻辑统一处理只把最底层的网络调用留给子类的fetch()CustomFetchOptions接口传给具体客户端fetch()的每请求扩展选项代理 URL、Cookie Jar、浏览器指纹、是否忽略 TLS 错误FetchHttpClient类基于 Node.js 原生fetch的实现零依赖、最轻量但不支持代理ResponseWithUrl/IResponseWithUrl类 / 接口携带原始请求 URL 的Response子类用于让调用方拿到最终请求的完整 URL这套抽象的设计意图很清晰sendRequest()是公共入口fetch()是扩展点。上层http-crawler、file-download、自定义请求发送只依赖sendRequest想要接入新的底层 HTTP 引擎如 impit、got-scraping只需实现一个子类覆盖fetch。这一约定与 packages/types/src/http-client.ts 中定义的BaseHttpClient接口完全一致——接口只暴露一个sendRequest(request, options)方法。二、BaseHttpClient公共请求入口与横切逻辑BaseHttpClient是抽象基类其构造签名与公开方法如下export abstract class BaseHttpClient implements BaseHttpClient_2 { constructor(options?: { logger?: CrawleeLogger; }); protected abstract fetch(input: Request, init?: RequestInit CustomFetchOptions): PromiseResponse; sendRequest(initialRequest: Request, options?: SendRequestOptions): PromiseResponse; }关键点构造函数只接收可选的logger类型为crawlee/types中的CrawleeLogger用于告警日志输出例如 Cookie 读写失败时的warning记录见 packages/http-client/src/base-http-client.ts。fetch是protected abstract的受保护抽象方法——子类必须实现但外部调用方永远不直接调用它。它的职责被注释明确为执行原始网络请求不做任何自动重定向或特殊错误处理base-http-client.ts。sendRequest是唯一公开方法接收标准的Request对象和SendRequestOptions。2.1 SendRequestOptions每请求的可选上下文SendRequestOptions定义在 packages/types/src/http-client.tssendRequest会把它解析为实际执行参数选项类型说明sessionISession会话对象携带cookieJar、proxyInfo、fingerprint等状态cookieJarCookieJar显式指定 Cookie Jar优先级高于session.cookieJartimeoutMillisnumber请求超时毫秒数与signal一起通过AbortSignal.timeout实现signalAbortSignal用于取消请求的外部信号proxyUrlstring覆盖会话中代理的 URL注意手动设置可能干扰会话的代理轮换ignoreTlsErrorsboolean忽略 TLS 证书错误也可由session.proxyInfo.ignoreTlsErrorsMITM 代理触发2.2 请求上下文的解析优先级resolveRequestContextbase-http-client.ts把SendRequestOptions归一化为每次fetch调用所需的四要素遵循明确的优先级const proxyUrl options?.proxyUrl ?? options?.session?.proxyInfo?.url; const cookieJar options?.cookieJar ?? options?.session?.cookieJar ?? (await this.#createDefaultCookieJar()); const signal this.createAbortSignal(options?.signal, options?.timeoutMillis); // fingerprint 与 ignoreTlsErrors 也来自 session / options即显式选项优先于 sessionsession 优先于默认值。没有显式 Cookie Jar 且没有 session 时会懒加载tough-cookie创建一个全新的CookieJarbase-http-client.ts。超时与外部信号可以共存createAbortSignal在两者都存在时使用AbortSignal.any合并否则取其一base-http-client.ts。2.3 sendRequest 的完整执行流程sendRequest的循环体base-http-client.ts依次完成四件事发送前注入 CookieapplyCookies把 Cookie Jar 中的 Cookie 合并进请求头。若请求头已带有Cookie则克隆 Jar、把头部 Cookie 并入克隆体再取串——这样头部临时 Cookie 不会被持久化回会话base-http-client.ts。调用子类fetch显式传redirect: manual关闭引擎自身的自动重定向由基类统一接管。响应后回写 CookiesetCookies遍历response.headers.getSetCookie()中的Set-Cookie写入 Jarbase-http-client.ts。判断与跟随重定向isRedirect判断状态码在 300–399 且带Location头base-http-client.tsbuildRedirectRequest构造下一个请求最多跟随10 次超过则抛出Too many redirects错误base-http-client.ts。重定向请求的构建遵循 HTTP 规范base-http-client.ts303 See Other或301/302 且原方法为 POST时方法改写为GET、清空 body其他情况保留原方法并克隆初始请求的 body请求头从当前请求拷贝redirect始终保持manual。这意味着Cookie、代理、指纹在同一重定向链上会持续生效直到最终响应返回这是爬虫场景下非常关键的行为保证。三、CustomFetchOptions子类 fetch 的扩展选项CustomFetchOptions是基类传给子类fetch()的附加参数也是自定义客户端最需要关注的结构export interface CustomFetchOptions { cookieJar?: CookieJar; fingerprint?: SessionFingerprint; ignoreTlsErrors?: boolean; proxyUrl?: string; }其源码注释packages/http-client/src/base-http-client.ts明确说明proxyUrl本请求生效的代理 URL来自SendRequestOptions.proxyUrl或session.proxyInfo.urlcookieJar本请求的 Cookie Jar来自显式选项、session.cookieJar或新建的默认 JarfingerprintSessionFingerprint提示包含browser、platform、device等字段见 packages/types/src/session.ts用于模拟特定浏览器它是建议而非强制各客户端按能力尽力应用如 impit 将其映射到 TLS 指纹模拟配置无法支持的部分直接忽略ignoreTlsErrors忽略 TLS 证书校验来自显式选项或 MITM 代理session.proxyInfo.ignoreTlsErrors同样是尽力而为。由于fetch的签名是fetch(input: Request, init?: RequestInit CustomFetchOptions)子类可以在标准RequestInit如signal、redirect之外拿到这些扩展字段——这是抽象层与具体引擎之间的唯一契约。四、FetchHttpClient基于原生 fetch 的最简实现FetchHttpClient是随包提供的开箱即用实现packages/http-client/src/fetch-http-client.ts完整源码只有二十余行export class FetchHttpClient extends BaseHttpClient { override async fetch(request: Request, options?: RequestInit CustomFetchOptions): PromiseResponse { if (options?.ignoreTlsErrors) { this.#logger?.warningOnce( FetchHttpClient cannot disable TLS certificate verification, the ignoreTlsErrors option is ignored. Install the optional crawlee/impit-client dependency to make it work., ); } return fetch(request, options); } }它直接委托给 Node.js 全局fetch因此零额外依赖、实现最简单适合对性能和依赖体积敏感的场景不支持代理类注释明确写道 This implementation does not support proxyingfetch-http-client.ts。传入了proxyUrl也不会生效不支持关闭 TLS 校验遇到ignoreTlsErrors: true时只打印一次warningOnce提示安装crawlee/impit-client然后照常请求。对比GotScrapingHttpClient 如何利用同一抽象把 packages/got-scraping-client/src/index.ts 与FetchHttpClient对比可以直观看到抽象的可扩展性。GotScrapingHttpClient同样继承BaseHttpClient并实现fetch但内部调用gotScraping支持proxyUrl传给 got-scraping 的proxyUrl选项支持ignoreTlsErrors映射为https: { rejectUnauthorized: false }通过followRedirect: redirect follow配合基座的手动重定向逻辑用ResponseWithUrl包裹响应把 got 的url最终请求地址暴露给调用方。由此可见引擎的差异原生 fetch 还是 got-scraping被完全封装在fetch一层重定向、Cookie 等复杂逻辑由基类统一兜底。仓库内同样基于此抽象的实现还有crawlee/impit-client支持浏览器指纹模拟和crawlee/http-client各实现完整列表可查看 packages/http-crawler/src/internals/http-crawler.ts 中httpClient的接入方式。五、ResponseWithUrl携带最终 URL 的 Response标准Response本身不保证暴露最终请求 URL重定向后尤其如此而爬虫经常需要知道实际落地的地址。ResponseWithUrl解决这个问题export interface IResponseWithUrl extends Response { url: string; } export class ResponseWithUrl extends Response implements IResponseWithUrl { constructor(body: BodyInit | null, init: ResponseInit { url?: string; }); url: string; }实现细节packages/http-client/src/response.ts有两个值得注意的点空 body 状态码处理参考 undici 的常量表当状态码为101、204、205、304时强制把 body 置为null避免对无 body 响应调用new Response(body)时的歧义response.ts完全兼容原生Response它继承自 fetch API 的Response可以无缝用在response.json()、response.text()、response.arrayBuffer()等所有标准方法上只是额外多了一个url字段。GotScrapingHttpClient正是用它来携带 got-scraping 返回的gotResult.url见 packages/got-scraping-client/src/index.ts。六、在爬虫中的实际使用HttpCrawler 与文件下载BaseHttpClient的sendRequest是crawlee/http-crawler的核心依赖。从源码中可以确认两处关键调用packages/http-crawler/src/internals/http-crawler.ts 在爬虫主流程中调用this.httpClient.sendRequest(...)获取页面响应packages/http-crawler/src/internals/file-download.ts 在文件下载场景中把context.request转为fetchAPI 的Request后调用sendRequest用于下载 HTML、PDF、图片等二进制文件。从源码结构可以推断只要某个 HTTP 客户端实现了BaseHttpClient抽象sendRequest它就能被http-crawler直接使用。仓库提供了两个官方可选实现crawlee/got-scraping-client——基于 got-scraping支持代理与 TLS 配置crawlee/impit-client——支持浏览器指纹模拟会把SessionFingerprint.browser映射到对应的 TLS 指纹画像并支持关闭 TLS 校验。选择建议场景推荐客户端零依赖、最小体积、无代理需求FetchHttpClient内置默认需要代理轮换 / MITM 代理GotScrapingHttpClient或ImpitHttpClient需要浏览器指纹模拟、需要ignoreTlsErrors真正生效ImpitHttpClient七、自定义一个 HTTP 客户端扩展点总结基于以上分析接入自定义 HTTP 引擎只需三步继承BaseHttpClient构造函数透传{ logger }实现protected fetch()读取CustomFetchOptions中的proxyUrl、cookieJar、fingerprint、ignoreTlsErrors把Request翻译成引擎的调用参数响应统一用ResponseWithUrl或原生Response包装返回交给爬虫使用通过HttpCrawler的httpClient选项注入。基类会免费提供Cookie 注入与回写、最多 10 次的规范重定向跟随、超时与取消信号合并、Too many redirects防护等能力。这正是该包少而精的设计哲学——公共 API 只有 5 个符号却支撑起 Crawlee 整个纯 HTTP 爬取体系的可扩展性。【免费下载链接】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),仅供参考
返回列表