ARTICLE DETAIL

资讯详情

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

Crawlee CheerioCrawler 部署到 GCP Cloud Functions:完整改造与实战指南

Crawlee CheerioCrawler 部署到 GCP Cloud Functions:完整改造与实战指南 Crawlee CheerioCrawler 部署到 GCP Cloud Functions完整改造与实战指南【免费下载链接】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基于纯 HTTP 请求与 Cheerio 解析器工作不依赖浏览器进程因此非常适合运行在 Google Cloud Functions 这类轻量 FaaS 平台上。本文以仓库 gcp-cheerio.md 为骨架逐步讲解如何把本地 Crawlee 项目改造成可在 GCP Cloud Functions 中运行并返回抓取数据的形态同时结合仓库源码说明persistStorage、Configuration等关键机制背后的实现原理。读完本文你将掌握「改造项目 → ZIP 上传部署 → 在线测试」的完整流程。为什么需要改造Cloud Functions 的环境约束在本地开发时Crawlee 默认会把数据集、请求队列、键值存储等内容持久化到磁盘上的storage目录方便断点续爬与调试。但 GCP Cloud Functions 是典型的无状态 FaaS 环境它具备以下特点决定了我们不能直接原样上传本地项目无持久化文件系统保障函数实例的生命周期短且随时可能被回收依赖磁盘的存储方案不可靠实例可能被复用函数执行结束后容器可能存活一段时间以降低冷启动延迟残留的内存状态会污染下一次调用无 Layers 机制与 AWS Lambda 不同GCP Cloud Functions 不支持把依赖打包成单独的 Layer而是根据package.json自动安装依赖详见下文「部署」一节以 HTTP 请求触发函数通过触发器接收请求并返回响应抓取逻辑必须包裹在符合平台约定的入口函数中。因此改造工作只需要两件事关闭磁盘持久化改用内存存储以及把爬虫逻辑包裹进一个可导出的 handler 函数。第一步创建项目并设置入口文件在本地执行脚手架命令创建 Crawlee 项目npx crawlee create创建完成后修改项目根目录下的package.json把main字段指向src/main.js。GCP Cloud Functions 会依据该字段定位入口模块{ name: my-crawlee-project, version: 1.0.0, main: src/main.js, ... }仓库内置的 Cheerio TypeScript 模板见 packages/templates/templates/cheerio-ts/package.json展示了标准项目结构源码位于src/下包含main.ts与路由文件start:dev使用tsx运行、start:prod运行编译产物。如果你选用 TypeScript部署前需先执行构建并把入口指向编译后的dist/main.js本文按文档使用 JavaScript 版本。第二步传入独立 Configuration 并关闭持久化存储打开src/main.js需要做的第一个改动是给爬虫构造函数传入一个独立的Configuration实例并设置persistStorage: falseimport { CheerioCrawler, Configuration } 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);为什么必须是「独立」的 ConfigurationCrawlee 默认维护一个全局共享的配置单例Configuration.getGlobalConfiguration()见 packages/core/src/configuration.ts所有爬虫实例默认共享同一套存储。在本地开发这很便利但在 FaaS 环境下会导致「状态残留」上一次调用写入的数据会被下一次调用读到引发极难排查的偶发问题。因此每次运行都要通过构造函数传入全新的Configuration实例保证调用之间相互隔离、函数保持无状态。persistStorage: false 的底层机制从源码看persistStorage是 Crawlee 核心配置字段之一默认值为true并可通过环境变量CRAWLEE_PERSIST_STORAGE覆盖见 configuration.ts。它的作用体现在存储后端的选型上在 service_locator.ts 中getStorageBackend()会根据配置决定创建哪种存储后端——persistStorage: true默认→FileSystemStorageBackend数据落盘到storageDir指定的目录默认./storagepersistStorage: false→MemoryStorageBackend数据仅保存在内存中函数结束即释放。配置解析遵循「构造函数选项 环境变量 crawlee.json schema 默认值」的优先级链见 configuration.ts且Configuration一旦创建便不可变更对属性的赋值会抛出TypeError见 configuration.ts因此所有选项必须在构造时一次传齐。提示如果不想改代码也可以在 GCP 控制台中为函数设置环境变量CRAWLEE_PERSIST_STORAGEfalse达到同样效果但显式传入Configuration更清晰也避免了共享全局状态。第三步包裹 handler 函数并返回数据第二个改动是把爬虫调用包裹进一个handler 函数并将其从src/main.js以**命名导出named export**的方式暴露。该函数需要满足可以是异步函数async接收两个位置参数req包含用户请求 Cloud Function 的详细信息和res可修改的响应对象通过res.send(data)返回数据。import { CheerioCrawler, Configuration } from crawlee; import { router } from ./routes.js; const startUrls [https://crawlee.dev]; export const handler async (req, res) { const crawler new CheerioCrawler({ requestHandler: router, }, new Configuration({ persistStorage: false, })); await crawler.run(startUrls); return res.send(await crawler.getData()) }这里有两个关键点值得展开crawler.getData()爬虫运行结束后抓取结果会写入默认数据集Dataset。由于persistStorage: false数据集只存在于内存中函数返回前调用getData()取出全部结果并通过res.send()以 JSON 形式返回给调用方。每次调用都新建爬虫实例把new CheerioCrawler(...)放在 handler 内部而非模块顶层确保每次函数调用都从零开始。这与 AWS Lambda 场景下的建议完全一致——平台会在首次执行后保留运行环境一段时间以降低冷启动若爬虫实例被复用数据集、会话池等状态就会在多次调用间泄漏可对照仓库中 aws-cheerio.md 的「Keep your Lambda stateless」提示。补充CheerioCrawler在仓库中的实现位于 packages/cheerio-crawler/src/internals/cheerio-crawler.ts它继承自DOMCrawler位于crawlee/http包构造函数将所有选项透传给父类并注入 Cheerio 解析器。也就是说本指南的改造思路同样适用于其他基于 HTTP 的爬虫变体如HttpCrawler、JsdomCrawler等浏览器类爬虫在 GCP 上则需要改走 Cloud Run 容器方案详见仓库中的 gcp-browsers.md。第四步部署到 Google Cloud Platform1. 创建并配置函数在 Google Cloud 控制台进入 Cloud Functions创建一个新函数并按需配置内存与 CPU根据目标网站的响应体大小与并发量分配Cheerio 爬虫不加载浏览器通常不需要大内存但抓取大页面时可适当提高区域Region选择离目标站点较近的区域以降低网络延迟函数超时TimeoutCloud Functions 默认超时较短需要根据一次抓取任务的总耗时上调。2. 选择 ZIP 上传部署方式选择ZIP Upload。在此之前需要创建一个 GCP 存储桶Storage Bucket用于存放上传的 zip 包。3. 打包项目文件打包时排除node_modules文件夹。这是与 AWS Lambda 的关键差异GCP Cloud Functions 没有类似 Lambda Layers 的机制但它会在部署时根据package.json自动安装依赖。因此 zip 包只需包含源码与清单文件例如zip -r my-function.zip . -x node_modules/*4. 设置 Entry point在函数配置中将Entry point设置为从src/main.js导出的函数名——即上文的handler。GCP 会根据package.json的main字段定位到src/main.js再从该模块中查找与 Entry point 同名的导出函数。第五步测试函数部署完成后在函数详情页点击Testing测试标签页。该页会生成一段调用 Cloud Function 的curl脚本直接运行即可验证函数是否按预期返回抓取数据。如果你不想在本地安装gcloudCLI可以点击测试页面上方的 Cloud Shell 链接在浏览器内的云端终端中直接运行这段curl脚本无需任何本地环境准备。常见问题与最佳实践保持函数无状态不要把爬虫实例、Configuration、数据集引用放在模块顶层所有状态都应在 handler 内部创建调用结束即销毁。结果即响应由于persistStorage: false数据不会落盘必须在 handler 内通过getData()取出并res.send()返回否则数据将随实例销毁而丢失。超时与内存抓取大型站点时请确保函数超时设置覆盖整个爬取过程若遇超时可拆分为多次调用或考虑迁移到 Cloud Run 容器方案gcp-browsers.md。与 AWS Lambda 的差异AWS 版指南要求打包时包含node_modules或改用 Lambda Layers而 GCP 版要求排除它两者都要求persistStorage: false和「每次调用新建爬虫实例」这说明无状态原则是所有 FaaS 平台通用的核心约束。进一步参数化handler 的req参数携带用户请求信息可以根据请求内容动态决定startUrls或抓取深度把 Cloud Function 变成一个可复用的抓取 API。总结把 Crawlee 的CheerioCrawler项目部署到 GCP Cloud Functions只需三步设置main字段、传入带persistStorage: false的独立Configuration、把爬虫逻辑包裹进命名导出的handler函数并返回getData()结果。底层来看persistStorage: false会让存储后端从FileSystemStorageBackend切换为MemoryStorageBackend从而适配无状态、无持久化磁盘的 FaaS 环境。整个改造轻量且可复制是 GCP 上运行轻量级 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),仅供参考
返回列表