
在 GCP Cloud Run 上部署帶瀏覽器的 Crawlee 爬蟲Playwright/Chromium 全指南【免費(fèi)下載鏈接】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.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/cr/crawlee本文是一份面向 Node.js 開發(fā)者的實(shí)戰(zhàn)部署指南講解如何將使用 Playwright、Puppeteer 等瀏覽器驅(qū)動(dòng)的 Crawlee 爬蟲部署到 Google Cloud PlatformGCP的 Cloud Run 服務(wù)上。你會(huì)掌握為什么 Cloud Functions 無(wú)法直接運(yùn)行 Chromium、如何用Configuration關(guān)閉本地持久化、如何用 Express 把爬蟲包裝成 HTTP 服務(wù)以及通過(guò)gcloud run deploy一鍵上云并處理首次運(yùn)行失敗的調(diào)優(yōu)方法。為什么是 Cloud Run而不是 Cloud Functions在 GCP 上運(yùn)行完整版瀏覽器爬蟲與在 AWS Lambda 上運(yùn)行有顯著差異Cloud Functions 的最新運(yùn)行時(shí)缺少運(yùn)行 Chromium 所必需的依賴這是 Puppeteer 官方排查文檔中記錄的已知問(wèn)題。因此要讓瀏覽器版的 Crawlee 爬蟲在 GCP 上運(yùn)行需要轉(zhuǎn)向Cloud Run——GCP 面向 Docker 容器的托管平臺(tái)。除此之外它的使用方式與 Cloud Functions / AWS Lambda 幾乎完全一致。Cloud Run 的核心特性對(duì)應(yīng)本倉(cāng)庫(kù)中的 docs/deployment/gcp-browsers.md 說(shuō)明按需拉起容器GCP 會(huì)在收到請(qǐng)求時(shí)才啟動(dòng)你的容器你只為容器從收到請(qǐng)求到返回 HTTP 響應(yīng)之間的運(yùn)行時(shí)間付費(fèi)冷啟動(dòng)不產(chǎn)生費(fèi)用本地可調(diào)試相比傳統(tǒng) FaaSCloud Run 提供了更好的開發(fā)體驗(yàn)——你可以先在本地把 Docker 容器跑起來(lái)調(diào)試確保與云端拿到完全一致的運(yùn)行環(huán)境再部署上去。這一模型意味著你的爬蟲代碼必須被打包進(jìn) Docker 鏡像并且對(duì)外暴露一個(gè) HTTP 服務(wù)入口。準(zhǔn)備項(xiàng)目關(guān)閉持久化存儲(chǔ)無(wú)論部署到哪個(gè) FaaS/容器平臺(tái)第一步都是在創(chuàng)建爬蟲時(shí)傳入一個(gè)新的Configuration實(shí)例并關(guān)閉存儲(chǔ)持久化import { Configuration, PlaywrightCrawler } from crawlee; import { router } from ./routes.js; const startUrls [https://crawlee.dev]; const crawler new PlaywrightCrawler({ requestHandler: router, }, new Configuration({ persistStorage: false, })); await crawler.run(startUrls);從倉(cāng)庫(kù)源碼看persistStorage是Configuration的內(nèi)置配置字段之一定義于 packages/core/src/configuration.ts/** default true */ persistStorage: field(coerceBoolean.default(true), CRAWLEE_PERSIST_STORAGE), /** default ./storage */ storageDir: field(z.string().default(./storage), CRAWLEE_STORAGE_DIR),這意味著persistStorage默認(rèn)值為true在無(wú)狀態(tài)容器環(huán)境中必須顯式關(guān)閉否則 Crawlee 會(huì)嘗試把 RequestQueue、Dataset、KeyValueStore 等狀態(tài)寫入本地./storage目錄storageDir的默認(rèn)值而容器實(shí)例隨時(shí)可能被回收該字段同樣支持通過(guò)環(huán)境變量CRAWLEE_PERSIST_STORAGE覆蓋適合在 Dockerfile 或 Cloud Run 環(huán)境配置中統(tǒng)一管理根據(jù) packages/core/src/configuration.ts 中聲明的解析優(yōu)先級(jí)構(gòu)造函數(shù)參數(shù) 環(huán)境變量 crawlee.json schema 默認(rèn)值。因此直接傳入new Configuration({ persistStorage: false })是最高優(yōu)先級(jí)的做法不會(huì)被環(huán)境變量意外覆蓋。關(guān)閉持久化后爬取的數(shù)據(jù)仍會(huì)存放在內(nèi)存中的 Dataset 里可以在爬取結(jié)束后通過(guò)crawler.getData()一次性取出對(duì)應(yīng) packages/core/src/storages/dataset.ts 的Dataset.getData()返回DatasetContent對(duì)象內(nèi)含items數(shù)組及total、offset、count、limit等分頁(yè)信息。用 Express 包裝 HTTP 處理器Cloud Run 平臺(tái)看到的只是一個(gè)不透明的 Docker 容器它不關(guān)心你的應(yīng)用內(nèi)部是什么框架只要求容器內(nèi)的 HTTP 服務(wù)在指定端口上監(jiān)聽(tīng)。因此我們需要自己動(dòng)手把爬蟲包裝進(jìn)一個(gè) Express HTTP 服務(wù)器。PORT 環(huán)境變量GCP 會(huì)向容器注入一個(gè)名為PORT的環(huán)境變量你的 HTTP 服務(wù)器必須監(jiān)聽(tīng)這個(gè)端口GCP 才會(huì)把該端口暴露給外部世界。代碼里要讀取并解析它app.listen(parseInt(process.env.PORT) || 3000);parseInt(process.env.PORT) || 3000的寫法兼顧了云端使用 GCP 注入的PORT與本地開發(fā)未設(shè)置時(shí)回退到 3000兩種場(chǎng)景。最終完整的 main.js將爬蟲邏輯放進(jìn) Express 的 GET 路由處理器中完整腳本如下import { Configuration, PlaywrightCrawler } from crawlee; import { router } from ./routes.js; import express from express; const app express(); const startUrls [https://crawlee.dev]; app.get(/, async (req, res) { const crawler new PlaywrightCrawler({ requestHandler: router, }, new Configuration({ persistStorage: false, })); await crawler.run(startUrls); return res.send(await crawler.getData()); }); app.listen(parseInt(process.env.PORT) || 3000);無(wú)狀態(tài)是硬性要求和所有 FaaS 平臺(tái)一樣Cloud Run 的請(qǐng)求處理器必須保持無(wú)狀態(tài)stateless每次請(qǐng)求到達(dá)時(shí)在處理器內(nèi)部創(chuàng)建爬蟲實(shí)例用完即棄不要在請(qǐng)求之間共享爬蟲、瀏覽器實(shí)例或內(nèi)存中的數(shù)據(jù)集狀態(tài)——容器實(shí)例可能隨時(shí)被水平伸縮、重建或回收數(shù)據(jù)要么在單次請(qǐng)求內(nèi)通過(guò)crawler.getData()返回給客戶端要么發(fā)送到外部存儲(chǔ)如數(shù)據(jù)庫(kù)、對(duì)象存儲(chǔ)絕不能依賴本地文件系統(tǒng)保存跨請(qǐng)求狀態(tài)。部署到 GCP準(zhǔn)備 Dockerfile如果項(xiàng)目是通過(guò)npx crawlee create初始化的初始化腳本已經(jīng)為你準(zhǔn)備好了現(xiàn)成的Dockerfile。以倉(cāng)庫(kù)中的 Playwright TypeScript 模板packages/templates/templates/playwright-ts/Dockerfile為例它采用了兩階段構(gòu)建# 第一階段構(gòu)建 FROM apify/actor-node-playwright-chrome:24-1.58.2 AS builder COPY --chownmyuser package*.json ./ RUN npm install --includedev --auditfalse COPY --chownmyuser . ./ RUN npm run build # 第二階段精簡(jiǎn)運(yùn)行鏡像 FROM apify/actor-node-playwright-chrome:24-1.58.2 COPY --frombuilder --chownmyuser /home/myuser/dist ./dist COPY --chownmyuser package*.json ./ RUN npm --quiet set progressfalse \ npm install --omitdev \ echo Installed NPM packages: \ (npm list --omitdev --all || true) \ echo Node.js version: \ node --version \ echo NPM version: \ npm --version COPY --chownmyuser . ./ CMD ./start_xvfb_and_run_cmd.sh npm run start:prod --silent這個(gè) Dockerfile 的幾個(gè)關(guān)鍵點(diǎn)基礎(chǔ)鏡像apify/actor-node-playwright-chrome已預(yù)裝 Chromium 及 Playwright 運(yùn)行所需系統(tǒng)依賴這正是 Cloud Functions 缺失而容器方案能解決的更多可用鏡像見(jiàn) docs/guides/docker_images.mdx先拷貝package.json再執(zhí)行依賴安裝充分利用 Docker 層緩存加速后續(xù)構(gòu)建生產(chǎn)階段使用--omitdev跳過(guò)開發(fā)依賴控制鏡像體積CMD中通過(guò)start_xvfb_and_run_cmd.sh啟動(dòng) XVFB 虛擬顯示保證 headful 模式下瀏覽器也能在無(wú)顯示器容器中運(yùn)行package.json中的start:prod對(duì)應(yīng)node dist/main.js若你的項(xiàng)目由倉(cāng)庫(kù)中的其他模板如 puppeteer-ts、cheerio-ts見(jiàn) packages/templates/templates/初始化同樣會(huì)生成對(duì)應(yīng)的 Dockerfile思路一致。執(zhí)行 gcloud run deploy在包含 Dockerfile 的項(xiàng)目目錄下執(zhí)行g(shù)cloud run deploygcloudCLI 會(huì)引導(dǎo)你回答幾個(gè)問(wèn)題主要包括部署區(qū)域region選擇離目標(biāo)網(wǎng)站或用戶較近的區(qū)域是否允許未認(rèn)證訪問(wèn)public/private即應(yīng)用是否對(duì)外公開還是僅限項(xiàng)目?jī)?nèi)調(diào)用?;卮鹜戤吅髴?yīng)用會(huì)出現(xiàn)在 GCP 控制臺(tái)的 Cloud Run 面板中并分配一個(gè)訪問(wèn)鏈接通過(guò)該鏈接即可觸發(fā)爬蟲運(yùn)行。首次運(yùn)行失敗的調(diào)優(yōu)如果新創(chuàng)建的 Cloud Run 服務(wù)第一次執(zhí)行就失敗通常需要編輯 Run 的配置內(nèi)存建議設(shè)置為1GiB 或更高。Chromium 實(shí)例本身的內(nèi)存占用較大加上 Node.js 運(yùn)行時(shí)與爬蟲數(shù)據(jù)結(jié)構(gòu)默認(rèn)配額很容易觸頂請(qǐng)求超時(shí)根據(jù)你抓取的目標(biāo)網(wǎng)站規(guī)模調(diào)整請(qǐng)求超時(shí)時(shí)間。大頁(yè)面、慢站點(diǎn)、多級(jí)爬取鏈路都會(huì)顯著拉長(zhǎng)單次請(qǐng)求耗時(shí)超時(shí)過(guò)短會(huì)導(dǎo)致容器被提前終止。關(guān)聯(lián)閱讀想要無(wú)瀏覽器、純 HTTP 的輕量方案部署到 GCP可參考 docs/deployment/gcp-cheerio.md同樣的思路部署到 AWS Lambda 的瀏覽器版本見(jiàn) docs/deployment/aws-browsers.md 與 docs/deployment/aws-cheerio.mdApify 平臺(tái)Crawlee 的原生托管環(huán)境部署方式見(jiàn) docs/deployment/apify_platform.mdxDocker 鏡像選型與自定義見(jiàn) docs/guides/docker_images.mdx本指南的版本化文檔位于 website/versioned_docs/version-3.16/deployment/gcp-browsers.md倉(cāng)庫(kù)的現(xiàn)行版本見(jiàn) docs/deployment/gcp-browsers.md?!久赓M(fèi)下載鏈接】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.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/cr/crawlee創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考