ARTICLE DETAIL

资讯详情

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

Crawlee HttpCrawler 实战指南:用纯 HTTP 请求构建高吞吐网页抓取任务

Crawlee HttpCrawler 实战指南:用纯 HTTP 请求构建高吞吐网页抓取任务 Crawlee HttpCrawler 实战指南用纯 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/crawleeCrawlee 的crawlee/http包提供HttpCrawler——一个基于纯 HTTP 请求的并行网页抓取框架它不加载浏览器、不做 HTML 解析因而在数据带宽和速度上极具优势。本文以 packages/http-crawler/README.md 为骨架结合该包的源码实现src/internals/http-crawler.ts深入讲解其工作原理、URL 来源、MIME 类型过滤、并发控制与全部核心配置项。读完本文你将能独立用HttpCrawler搭建一个快速、可靠、可递归抓取的文本/JSON 数据采集任务并理解其与 Puppeteer/Playwright 爬虫的适用边界。HttpCrawler 是什么定位与适用边界HttpCrawler为使用普通 HTTP 请求并行爬取网页提供了一套完整框架。它有两个决定性特征见 类注释每个 URL 通过一次普通 HTTP 请求下载请求本身不依赖浏览器内核不进行任何 HTML 解析下载下来的响应体原样交给你的requestHandler处理。正因为省去了浏览器启动与页面渲染的开销它在数据带宽利用率上非常高效。但代价是如果目标网站必须依赖 JavaScript 才能展示内容HttpCrawler将无法拿到渲染后的数据。此时应改用PuppeteerCrawler或PlaywrightCrawler——它们会用功能完整的 headless Chrome 加载页面自然能执行 JS。三者共享相同的爬取抽象Request、Dataset、Session、并发控制切换成本很低。另外请注意HttpCrawler默认只下载允许的 MIME 类型的响应体详见下文MIME 类型过滤一节对于被跳过的资源会直接报错跳过这是它保持带宽高效的关键机制。最小可用示例README 给出的最小示例展示了HttpCrawler的核心用法构造实例、实现requestHandler、传入 URL 列表并运行。import { HttpCrawler, Dataset } from crawlee/http; const crawler new HttpCrawler({ requestList, async requestHandler({ request, response, body, contentType }) { // Save the data to dataset. await Dataset.pushData({ url: request.url, html: body, }); }, }); await crawler.run([ http://www.example.com/page-1, http://www.example.com/page-2, ]);要点解读crawler.run(urls)会接收一个字符串数组作为待抓取 URL 的快捷入口更正式的做法是通过构造函数传入requestManager或兼容的requestList/requestQueue见下文。requestHandler解构出的body即响应体——对 HTML 页面它是字符串对其他类型它是Buffer详见 InternalHttpCrawlingContext 定义。Dataset.pushData将数据写入结果数据集本地模式下以 JSON 文件形式保存在./storage/datasets/default。爬虫会在没有更多 Request 对象可爬时自动结束await crawler.run(...)返回即代表全部任务完成。一个更贴近生产环境的完整示例可参考官方文档示例 docs/examples/http_crawler.ts它演示了minConcurrency、maxConcurrency、maxRequestRetries、requestHandlerTimeoutSecs、maxRequestsPerCrawl以及failedRequestHandler的组合使用对应说明文档见 docs/examples/http_crawler.mdx。URL 来源requestManager、RequestList 与 RequestQueue爬取的 URL 以Request对象表示来源有两条README 原文说明静态列表RequestList一次性给定的 URL 集合适合事先已知抓取范围、无需动态追加链接的场景动态队列RequestQueue可在爬取过程中不断入队新 URL是递归爬取网站的基础设施——解析当前页后把新发现的链接再次入队直到队列耗尽。在 Crawlee 4.x 中两者被统一抽象为request manager概念构造选项requestManager是主入口RequestQueue本身就是一种 request manager。而requestList与requestQueue这两个老选项仍被接受但已标记为弃用deprecated——构造函数会为兼容性把它们折叠进同一个requestManager见 类注释。如果你需要从只读的RequestList读取同时又能入队新链接的组合需求源码给出了标准解法通过requestLoader.toTandem()把RequestList与一个RequestQueue组合成RequestManagerTandem再将结果传给requestManager。这一机制在文档指南 request_loaders.mdx 及其示例如 request_loaders_rl_tandem_helper.ts中有更完整的演示。关于两个来源同时使用还有一个关键行为README 明确说明如果同时指定requestList和requestQueue爬虫会先处理RequestList中的 URL并在开始处理之前把所有 URL 自动入队到RequestQueue。这保证了同一个 URL 不会被重复爬取——所有 URL 最终统一由队列去重和调度。MIME 类型过滤默认白名单与 additionalMimeTypes这是HttpCrawler最值得注意的默认行为之一README 与源码一致确认默认情况下HttpCrawler只处理text/html和application/xhtmlxmlMIME 类型以Content-Type响应头为准的网页并跳过其他类型。而到了源码层面白名单更宽——默认 MIME 类型常量 包含五类MIME 类型说明text/htmlHTML 页面application/xhtmlxmlXHTML 页面text/xmlXML 文档application/xmlXML 文档application/jsonJSON 数据请求发出后abortDownloadOfBody 会在下载响应体前检查Content-Type若不在白名单内直接抛错并跳过该资源并标记request.noRetry true避免无意义重试从而省下下载整段响应体的带宽。如需处理更多类型使用构造选项additionalMimeTypesconst crawler new HttpCrawler({ additionalMimeTypes: [application/pdf, image/png], async requestHandler({ body }) { // body 此时是 Buffer }, });源码对它的处理extendSupportedMimeTypes值得注意支持通配符*/*——加入后所有MIME 类型的响应体都会被下载传入的每个 MIME 类型会经过content-type库严格解析无法解析的值会直接抛错Can not parse mime type ... from options.additionalMimeTypes解析时剥离参数只取type部分加入白名单集合。不同内容类型的解析行为也不同README 提醒Beware that the parsing behavior differsHTML/XML 文本会被解码成字符串JSON 会被解析成对象context.json其余类型则以Buffer原样呈现。详见下文requestHandler 爬取上下文一节。另外错误状态码的处理也在parseResponse中完成源码4xx/5xx 会注册状态码统计并抛错若错误响应是 JSON会尝试解析出message字段作为错误信息否则截取响应体前 100 字符作为错误描述。429 状态码handleBlockedRequestByContent之前的专门检查源码会读取retry-after头、触发域名级限速记录并抛出RequestThrottledError。requestHandler 爬取上下文body、json、contentType 与 Cheerio 辅助requestHandler收到的crawlingContextHttpCrawlingContext定义见 http-crawler.ts在基础上下文之上额外提供成员类型/行为request已成功加载的请求对象含loadedUrl属性实际跳转后的最终 URLresponse完整 HTTP 响应对象状态码、响应头、元数据body响应体。text/html、application/xhtmlxml、application/xml类型为字符串其余类型为Bufferjson当响应Content-Type为application/json时由响应体解析出的对象否则为nullcontentType解析后的{ type, encoding }结构waitForSelector(selector, timeoutMs?)等待匹配选择器的元素出现超时参数在 HttpCrawler 场景下被忽略parseWithCheerio(selector?, timeoutMs?)返回 Cheerio 句柄可用与CheerioCrawler完全相同的方式操作页面数据其中parseWithCheerio是HttpCrawler的一个重要能力补充虽然它本身不做 HTML 解析但上下文提供了按需加载 Cheerio 的辅助方法让你在需要时依然能方便地提取页面结构数据async requestHandler({ parseWithCheerio }) { const $ await parseWithCheerio(); const title $(title).text(); // ... 用 $ 做选择器提取 }该方法的实现processHttpResponse 源码本质是cheerio.load(body.toString())并在传入selector时先调用waitForSelector校验元素存在。导航钩子preNavigationHooks 与 postNavigationHooksHttpCrawler暴露两类导航钩子用于在请求发出前后干预流程preNavigationHooks选项定义在导航发起 HTTP 请求之前按顺序执行适合设置 Cookie、附加请求头等。README 给出的签名是preNavigationHooks: [ (crawlingContext, gotOptions) { // ... }, ],钩子可以可选地返回一个部分对象其属性会被合并进 crawling context从而为后续钩子与管道阶段覆盖上下文成员。上下文的构建顺序为基础上下文request、session、辅助方法等→extendContext→preNavigationHooks→ 导航 →postNavigationHooks→requestHandler。这意味着在 pre-navigation 阶段导航相关的成员response、body、$尚不可用。postNavigationHooks选项定义在导航之后执行适合校验导航是否成功钩子返回的部分对象可用于覆盖上下文例如解决验证码后重新拉取响应postNavigationHooks: [ async (crawlingContext) { if (await needsRevalidation(crawlingContext)) { return { response: await refetch(crawlingContext.request) }; } }, ],超时语义源码中preNavigationHooks、导航请求、postNavigationHooks共享同一个导航时间窗口navigationTimeoutSecs默认 30 秒见 optionsShape——一个慢钩子会消耗导航本身的预算而不是每个步骤单独计时buildContextPipeline 实现。这与只统计requestHandler耗时的requestHandlerTimeoutSecs是相互独立的两个超时。并发控制ConcurrencySystem 与三个关键参数HttpCrawler遵循 Crawlee 的统一并发模型新请求只有在系统有足够空闲 CPU 和内存时才会被调度由爬虫内部的ConcurrencySystem判定。通过构造函数可直接调节三个参数minConcurrency——最小并发数保证基础吞吐maxConcurrency——最大并发数硬性上限maxRequestsPerMinute——每分钟最大请求数用于限速礼貌抓取、规避封禁。若需要更精细的控制可以注入一个预配置的concurrencySystem实例完全替换默认系统。值得一提的实现细节HttpCrawler对纯 HTTP 场景做了专门的并发调优。它导出了常量 HTTP_OPTIMIZED_CONCURRENCY_SYSTEM_OPTIONS其默认值包括{ desiredConcurrency: 10, loadSignals: { eventLoop: { snapshotIntervalSecs: 2, maxBlockedMillis: 100, overloadedRatio: 0.7, }, }, }理由是纯 HTTP 抓取几乎不触碰事件循环因此采用更高的起始并发和更宽松的事件循环信号。默认并发系统由 createDefaultConcurrencySystem 把这些调优参数与用户的minConcurrency/maxConcurrency等快捷选项合并而成。但注意如果你自行注入concurrencySystem默认调优会被整体替换需要手动展开该常量以保留优化import { HttpCrawler, ConcurrencySystem, HTTP_OPTIMIZED_CONCURRENCY_SYSTEM_OPTIONS } from crawlee/http; const crawler new HttpCrawler({ concurrencySystem: new ConcurrencySystem({ ...HTTP_OPTIMIZED_CONCURRENCY_SYSTEM_OPTIONS, maxConcurrency: 50, }), // ... });并发模型与负载信号的完整讲解见文档指南 scaling_crawlers.mdx 及其示例如 scaling_crawlers_concurrencySystem.ts。编码处理suggestResponseEncoding 与 forceResponseEncoding很多网站存在响应头缺失或错误的编码声明导致响应体乱码。HttpCrawler内置了多层编码解析策略实现集中在 parseResponse 与 encodeResponse优先从Content-Type响应头解析 charset若无法解析则回退到按 URL 文件扩展名推断MIME 与 charsetmime-types库见 utils.ts。对 HTML/XML 类型且无 charset 信息时会扫描 HTML 文档前 1024 字节中的meta charset/meta http-equivContent-Type ...声明extractCharsetFromHtmlBytesutils.ts。仍然未知时使用suggestResponseEncoding如windows-1250兜底最终默认 UTF-8。对于 Node.js 不原生支持的编码如 windows-1250 等借助iconv-lite流式转码为 UTF-8。两个相关选项README 均有说明// 仅在响应头没有编码信息时兜底 suggestResponseEncoding: windows-1250, // 强制使用指定编码无视响应头声明 forceResponseEncoding: windows-1250,源码会在两者同时设置时打印警告并优先采用forceResponseEncoding构造函数。若响应声明了iconv也不支持的编码会抛出明确错误served with unsupported charset/encoding。其余核心配置项速查HttpCrawlerOptions完整定义见 http-crawler.ts除上文涉及外还包括选项默认值说明navigationTimeoutSecs30整个导航阶段pre 钩子 请求 post 钩子共享的超时窗口单位秒ignoreTlsErrorstrue是否忽略 TLS/SSL 证书错误透传给 HTTP 客户端内置 impit 与 got-scraping 客户端均支持原生 fetch 回退无法关闭 TLS 校验并会告警saveResponseCookiestrue自动把响应set-cookie中的 Cookie 保存到Session的 cookie jar后续请求带上置为false时写入被丢弃通过克隆 jar 实现见 requestAsBrowserpreNavigationHooks[]导航前钩子数组postNavigationHooks[]导航后钩子数组实现上还会自动前置一个按 MIME 白名单中止响应体下载的内置钩子additionalMimeTypes[]追加允许下载的 MIME 类型其余基础选项minConcurrency、maxConcurrency、maxRequestsPerMinute、maxRequestRetries、requestHandlerTimeoutSecs、failedRequestHandler、proxyConfiguration、sessionPoolOptions等继承自BasicCrawlerOptions行为与 Crawlee 其他爬虫一致。HTTP 客户端可替换性方面HttpCrawler通过httpClient抽象发送请求requestAsBrowser因此可无缝接入 impit 或 got-scraping 客户端详见文档指南 http-clients.mdx。会话与代理轮换的集成示例可参考 session_management_http.ts 与 proxy_management_integration_http.ts。路由分发createHttpRouter对于同一爬虫、多种页面、不同处理逻辑的场景HttpCrawler支持基于request.label的路由分发。包内导出了快捷工厂函数createHttpRouter源码等价于Router.createHttpCrawlingContext()import { HttpCrawler, createHttpRouter } from crawlee; const router createHttpRouter(); router.addHandler(label-a, async (ctx) { ctx.log.info(处理 label-a 的页面); }); router.addDefaultHandler(async (ctx) { ctx.log.info(处理其他页面); }); const crawler new HttpCrawler({ requestHandler: router, }); await crawler.run();路由机制在 Crawlee 中是跨爬虫的统一抽象更多细节见 core 路由源码 与 router.test.ts。生态扩展DOMCrawler、JSDOMCrawler 与 FileDownloadHttpCrawler是包内其他两类能力的基座DOMCrawlerdom-crawler.ts是HttpCrawler的子类它把响应体交给用户传入的DOMParser解析成 DOM并在上下文上附加enqueueLinks、extractLinks、waitForSelector、parseWithCheerio等辅助方法。JSDOMCrawler与LinkeDOMCrawler正是已选好解析器的DOMCrawler特化——它们通过相同的 HTTP 下载管道获取页面再用 jsdom/linkedom 解析介于纯 HTTP与完整浏览器之间可执行部分客户端脚本。FileDownloadfile-download.ts同样基于纯 HTTP 请求并行下载文件PDF、MP3、MKV 等任意类型不做内容解析上下文中的response.body以流形式供消费并内置MinimumSpeedStream下载速度过低时中止与ByteCounterStream下载进度日志两个辅助流。官方示例见 file_download.mdx 与 file_download_stream.mdx。crawlee/http的完整公开 API 清单见 docs/public-api/crawlee-http.api.md包配置与依赖见 packages/http-crawler/package.json。总结HttpCrawler是 Crawlee 家族中最快最省的成员纯 HTTP 下载、不做解析、按 MIME 白名单智能跳过资源配合自动调度的ConcurrencySystem与 HTTP 优化的默认并发参数非常适合文本、XML、JSON 类数据的大规模抓取。它支持静态列表与动态队列两种 URL 来源4.x 统一为requestManager模型、preNavigationHooks/postNavigationHooks导航钩子、多级编码兜底、Cookie 会话保存以及 Cheerio 按需解析当目标站点依赖 JS 渲染时再升级到 Puppeteer/Playwright 爬虫即可。以此为起点你可以放心地把它作为高吞吐采集管线的第一选择。【免费下载链接】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),仅供参考
返回列表