十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Crawlee 无服务器实战:将 CheerioCrawler 部署到 AWS Lambda 的完整指南

Crawlee 无服务器实战:将 CheerioCrawler 部署到 AWS Lambda 的完整指南 Crawlee 无服务器实战将 CheerioCrawler 部署到 AWS Lambda 的完整指南【免费下载链接】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 的 CheerioCrawler 是基于 Cheerio 的轻量级抓取方案本地开发非常方便npx crawlee create即可初始化项目但直接把它丢进 AWS Lambda 运行会遇到存储状态残留、文件系统只读、执行环境复用三大问题。本文以 Crawlee 3.12 版本文档为骨架结合当前仓库源码完整讲解如何改造代码、用内存存储替换文件存储、将爬虫包装为 Lambda handler并通过 zip 压缩包或 Lambda Layers 完成部署最终从 Lambda 中直接返回抓取数据。读完本文你将掌握一套可复制的「无状态 CheerioCrawler AWS Lambda」部署方案并理解其背后的存储后端切换原理。为什么本地能跑、Lambda 上却要改代码在本地npx crawlee create会生成一个开箱即用的 Crawlee 项目该命令由仓库中的 CreateProjectCommand.ts 实现。但 AWS Lambda 的运行环境与本地有本质差异主要体现在两点文件系统只读Lambda 提供的是只读根文件系统唯一的可写位置是/tmp而且/tmp也不保证持久。Crawlee 默认把 Dataset、RequestQueue、KeyValueStore 写到磁盘默认目录./storage直接运行必然失败。环境复用导致有状态AWS 为了降低冷启动时间会在一次执行结束后把运行环境保留一段时间后续调用会复用同一进程。如果 Crawlee 的所有实例共享同一份存储第二次调用就会读到第一次运行残留的状态产生极难排查的脏数据问题。因此部署前需要完成两类改造让每个 Lambda 调用使用独立的存储配置以及关闭磁盘持久化、改用内存存储。改造一为爬虫注入独立的 Configuration 实例Crawlee 默认所有爬虫实例共享同一份全局存储这在单进程场景下很方便但在 Lambda 中就是状态泄漏的根源。解决办法是每实例化一个爬虫就给它传一个全新的Configuration实例并且显式设置persistStorage: false。按 3.12 版本文档的写法Configuration作为构造函数的第二个参数传入// For more information, see https://crawlee.dev/ import { CheerioCrawler, Configuration, ProxyConfiguration } from crawlee; import { router } from ./routes.js; const startUrls [https://crawlee.dev]; const crawler new CheerioCrawler({ requestHandler: router, }, new Configuration({ persistStorage: false, })); await crawler.run(startUrls);其中persistStorage: false是关键它告诉 Crawlee 改用内存存储而不是文件系统存储。从当前仓库源码可以印证这一点——service_locator.ts 中getStorageBackend()会依据configuration.persistStorage的值在两种存储后端之间切换persistStorage为true默认时创建FileSystemStorageBackend数据落盘到configuration.storageDir默认./storagepersistStorage为false时创建MemoryStorageBackend数据全部保存在内存中天然适配 Lambda 只读文件系统。也就是说这一行配置直接决定了底层存储后端的选择而非仅仅少写点文件。关于persistStorage的默认值与优先级在 configuration.ts 中可以看到该字段的定义/** default true */ persistStorage: field(coerceBoolean.default(true), CRAWLEE_PERSIST_STORAGE),即persistStorage默认值为true对应环境变量CRAWLEE_PERSIST_STORAGE。因此如果你不想改代码也可以通过给 Lambda 设置环境变量CRAWLEE_PERSIST_STORAGEfalse达到同样效果。但文档推荐的显式传Configuration方式还有一个额外好处——它同时解决了存储共享问题。Configuration类本身是一个不可变值对象configuration.ts值在构造时一次性解析完毕之后任何赋值都会抛出TypeError。它的解析优先级从高到低为constructor options environment variables crawlee.json schema defaults该优先级链在resolveAll()configuration.ts中实现构造参数优先其次环境变量再其次项目根目录的crawlee.json文件读取逻辑见loadFileOptions()最后才是 schema 默认值。更全面的配置说明可参考 docs/guides/configuration.mdx。补充在当前主仓库v4的源码结构中CheerioCrawler的构造函数为constructor(options?: CheerioCrawlerOptions)见 cheerio-crawler.ts更推荐把配置放进 options 的configuration字段例如new CheerioCrawler({ requestHandler: router, configuration })。本文主体按 3.12 版本化文档的第二参数写法演示两种方式语义一致。改造二把爬虫逻辑包装成 Lambda handlerConfiguration注入完成后下一步是把所有逻辑包进一个handler函数——这就是 AWS 之后真正执行的Lambda 本体// For more information, see https://crawlee.dev/ import { CheerioCrawler, Configuration } from crawlee; import { router } from ./routes.js; const startUrls [https://crawlee.dev]; export const handler async (event, context) { const crawler new CheerioCrawler({ requestHandler: router, }, new Configuration({ persistStorage: false, })); await crawler.run(startUrls); };注意一个容易被忽略的细节new CheerioCrawler(...)和new Configuration(...)必须放在handler函数内部每次调用都新建实例而不是放在模块顶层只创建一次。为什么必须每次新建爬虫实例AWS 会在首次执行后让环境继续存活一段时间以减少冷启动因此后续调用会命中同一个已运行过的爬虫实例。若复用实例上次运行留在内存/存储中的数据会被本次调用读取到结果被污染爬虫的内部状态如 RequestQueue 游标、统计信息可能与新的输入不一致。文档的结论非常直接TLDR: Keep your Lambda stateless.让 Lambda 保持无状态。这是无服务器架构下使用 Crawlee 最重要的一条原则。改造三爬虫结束后返回抓取数据最后一步是让 Lambda 真正输出结果。Crawlee 的CheerioCrawler继承自BasicCrawler其getData()方法会打开默认 Dataset 并读取全部条目见 basic-crawler.ts 的实现内部调用Dataset.open()后执行dataset.getData(...args)。由于我们关闭了持久化存储数据直接从内存 Dataset 中取出。在crawler.run(startUrls)结束后调用它把结果作为 Lambda 响应体返回// For more information, see https://crawlee.dev/ import { CheerioCrawler, Configuration } from crawlee; import { router } from ./routes.js; const startUrls [https://crawlee.dev]; export const handler async (event, context) { const crawler new CheerioCrawler({ requestHandler: router, }, new Configuration({ persistStorage: false, })); await crawler.run(startUrls); return { statusCode: 200, body: await crawler.getData(), } };至此完整的src/main.js就绪每次调用新建无状态爬虫 → 内存存储 → 抓取 → 返回数据。其中requestHandler: router来自 Crawlee 模板生成的 routes.jssrc/routes.js用于按请求标签分发处理逻辑。部署打包上传与 Lambda 配置代码改造完成后进入部署环节。方式一直接上传 zip 压缩包在项目目录下执行zip -r package.zip .将整个项目包含node_modules文件夹打包然后在 AWS Lambda 控制台把package.zip作为代码源上传即可。方式二用 Lambda Layers 承载依赖推荐AWS 对直接上传有50MB 限制。Crawlee 项目本身通常远小于此限制但依赖树一旦庞大起来很容易超标。更稳妥的做法是用Lambda Layers单独托管node_modules把node_modules单独打包成 zip压缩包内应只有一个名为node_modules的文件夹将该压缩包上传到 AWS S3再基于该对象创建 Lambda Layer在 Lambda 函数配置中挂载这个 Layer。这样做的两个好处多个 Lambda 可以共享同一份依赖同时代码部分保持精简上传更快、更新更灵活。配置 handler 与测试上传代码后在 Lambda 的Runtime Settings中设置 handler。handler 的命名规则是用/表示目录层级用.表示具名导出。我们的 handler 名为handler从src/main.js导出因此填src/main.handler点击Test按钮发送一个测试事件即可触发运行。测试事件的具体内容暂时无关紧要——如果你后续想参数化爬虫可以解析 AWS 作为第一个参数传入 handler 的event对象例如把起始 URL 放进事件体。内存与临时存储配置建议在 AWS Lambda 控制台的Configuration标签页中可以调整函数内存大小与临时存储ephemeral storage大小内存大小会显著影响 Lambda 的执行速度CheerioCrawler 属于 CPU/IO 密集型更大的内存通常带来更强的 CPU 配额从而明显缩短抓取耗时若单次运行的数据量较大可适当调大 ephemeral storage以容纳内存之外的临时文件官方文档对内存与性能/成本的换算关系有详细说明可按需查阅。对于浏览器类爬虫Playwright/Puppeteer还需要额外处理浏览器二进制文件如通过sparticuz/chromium以 Lambda Layer 方式托管 Chromium、注入executablePath与args并建议将内存设置到1024MB 或以上、同步调大超时时间——这套方案在本文档的姊妹篇 docs/deployment/aws-browsers.md 中有完整讲解可作为下一步的参考。总结Lambda 上跑 CheerioCrawler 的四个要点注入独立Configuration每次实例化爬虫都传入新的Configuration避免多个调用共享存储导致状态泄漏persistStorage: false切换到底层MemoryStorageBackendservice_locator.ts适配 Lambda 只读文件系统也可通过环境变量CRAWLEE_PERSIST_STORAGEfalse等价实现handler 内每次新建爬虫保持 Lambda 无状态防止环境复用时访问到上次运行的实例getData()返回结果爬虫结束后从内存 Dataset 取数作为 Lambda 响应返回basic-crawler.ts。掌握这四点你就能把本地用npx crawlee create生成的 Cheerio 项目平滑迁移到 AWS Lambda按需触发、按量计费用无服务器的方式稳定运行你的抓取任务。【免费下载链接】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),仅供参考
返回列表