工程化網頁爬蟲(Crawlee):把採集腳本改造成可靠流水線

前言

寫採集腳本最常見的兩種結局:一種是跑一次就結束,沒有斷點續跑、沒有重試、沒有隊列,第二天要重來;另一種是寫得很快,跑起來之後被站點風控攔在門外,或者併發一上去就大量 429 / 連接重置,最後數據缺一半。

問題不在「能不能抓到」,而在「能不能穩定跑完」。這個 Skill 給出的是基於 Crawlee 的一套工程化方法論,把請求路由、反封禁、數據存儲、瀏覽器自動化這些事拆成明確的處理環節,目標是在 Node.js / Python 裏產出「跑得穩、拿得全」的採集流水線,而不是隨手寫的腳本。

這是什麼

一句話定位:這是一個把 Crawlee 的工程實踐整理成可調用方法論的 Skill,用於生成可靠的網頁採集流水線。

  • 出品方:崑崙增長(@kunlungrowth)
  • 版本:1.0.0
  • 來源:enterprise
  • 分類:dev-programming
  • 標籤:requires_api_key=false,即不依賴外部 API Key
  • SkillHub 頁面顯示:評分 100000,下載 1308,安裝 0
  • 官方地址:https://www.skillhub.cn/skills/kunlungrowth/python-node-web-crawler

它解決的問題在於:Crawlee 本身是一個功能較全的採集框架,能力分散在多個配置項和多種 Crawler 類型裏,第一次用的人很容易只寫出「一個默認 handler 從頭跑到尾」的代碼,漏掉路由分層、存儲落盤和瀏覽器池管理。這個 Skill 把這些決策點顯式化。

核心能力

下面列出的能力來自該 Skill 的公開簡介,逐條對應 Crawlee 中的具體機制。

請求路由。 用 router 把不同類型的請求分發到不同的處理邏輯,而不是把所有邏輯堆在一個默認 handler 裏。對應 Crawlee 的 crawler.router 與 default_handler 裝飾器。

反封禁。 控制請求節奏、瀏覽器指紋與請求頭一致性,使爬蟲行爲接近真實用戶。Crawlee 在默認配置下就提供了一套指紋與請求頭生成機制,包括 BrowserforgeFingerprintGenerator、BrowserforgeHeaderGenerator。

數據存儲。 採集結果統一落盤到 Dataset / 存儲目錄,不靠內存裏的 list 攢數據。對應 Dataset、push_data,以及運行後在當前工作目錄生成的 storage/ 目錄。

瀏覽器自動化。 需要執行客戶端 JavaScript 的場景走 PlaywrightCrawler,純 HTML 場景走 BeautifulSoupCrawler,兩者可按頁面類型混用。

自動擴縮容與重試。 由 AutoscaledPool 控制併發,失敗請求按策略重試,這是「跑得穩」的主要來源。

安裝與啓用

這個 Skill 的安裝入口在 SkillHub。它在 SkillHub 頁面上的座標是 @kunlungrowth/python-node-web-crawler,頁面當前顯示安裝數爲 0,公開資料中沒有給出 Cursor / Codex CLI / Claude Code 各自的專屬安裝命令,因此這裏不猜測命令格式。

啓用 Skill 之後,它所依託的 Crawlee 庫仍需要裝依賴。以下是 Crawlee 官方文檔中已覈實的安裝命令。

Python 側,裝全量特性並補齊瀏覽器依賴:

python -m pip install 'crawlee[all]'
playwright install

驗證安裝是否成功:

python -c 'import crawlee; print(crawlee.__version__)'

Python 側要求 3.10 及以上。

如果希望直接起一個項目骨架,可以用 Crawlee CLI 加模板:

uvx 'crawlee[cli]' create my-crawler

已經裝了 crawlee 的話,直接跑:

crawlee create my-crawler

Node.js / TypeScript 側對應的是 Apify 的 Crawlee for JS/TS 實現,倉庫地址 https://github.com/apify/crawlee 。Skill 簡介裏提到的 Node.js 支持即來自這一實現。

典型用法

以 Python 爲例。下面的示例來自 Crawlee 官方文檔,演示了一個最小可用的採集流程:註冊默認請求處理器、提取數據、落盤、繼續發現鏈接。

用 BeautifulSoupCrawler 處理靜態 HTML:

import asyncio

from crawlee.crawlers import BeautifulSoupCrawler, BeautifulSoupCrawlingContext


async def main() -> None:
    crawler = BeautifulSoupCrawler(
        # Limit the crawl to max requests. Remove or increase it for crawling all links.
        max_requests_per_crawl=10,
    )

    # Define the default request handler, which will be called for every request.
    @crawler.router.default_handler
    async def request_handler(context: BeautifulSoupCrawlingContext) -> None:
        context.log.info(f'Processing {context.request.url} ...')

        # Extract data from the page.
        data = {
            'url': context.request.url,
            'title': context.soup.title.string if context.soup.title else None,
        }

        # Push the extracted data to the default dataset.
        await context.push_data(data)

        # Enqueue all links found on the page.
        await context.enqueue_links()

    # Run the crawler with the initial list of URLs.
    await crawler.run(['https://crawlee.dev'])


if __name__ == '__main__':
    asyncio.run(main())

如果頁面內容依賴客戶端 JavaScript 渲染,換成 PlaywrightCrawler,處理邏輯的寫法保持一致:

import asyncio

from crawlee.crawlers import PlaywrightCrawler, PlaywrightCrawlingContext


async def main() -> None:
    crawler = PlaywrightCrawler(
        max_requests_per_crawl=10,
    )

    @crawler.router.default_handler
    async def request_handler(context: PlaywrightCrawlingContext) -> None:
        context.log.info(f'Processing {context.request.url} ...')

        data = {
            'url': context.request.url,
        }

        await context.push_data(data)
        await context.enqueue_links()

    await crawler.run(['https://crawlee.dev'])


if __name__ == '__main__':
    asyncio.run(main())

兩次運行都會在當前工作目錄下創建 storage/ 目錄存放數據。跑之前記得先執行 playwright install,否則 PlaywrightCrawler 會因瀏覽器依賴缺失而啓動失敗。

適用場景與注意

適合的場景:需要長時間運行、對完整性有要求的採集任務,例如站羣數據歸檔、週期性商品與資訊採集、多站點聚合。這類任務的共同點是「跑不完要接着跑」,所以請求隊列、斷點續跑和結構化存儲是硬需求。

需要注意的幾點:

1、max_requests_per_crawl 只是示例裏的調試上限,生產使用要去掉或調到實際需要的規模,否則採集會在 10 個請求後停止。
2、靜態頁面優先用 BeautifulSoupCrawler,性能明顯好於瀏覽器方案;只有確實需要執行客戶端 JS 時才上 PlaywrightCrawler,瀏覽器池的內存開銷要提前評估。
3、請求路由建議按站點或頁面類型拆 handler,不要把所有站點塞進一個默認 handler,否則後續調整某一類站點時會影響全局。
4、反封禁不是免死金牌。默認指紋和請求頭配置只能降低被識別的概率,遇到嚴格的風控仍需配合代理與速率策略,Skill 公開資料中未給出具體代理配置方案。
5、該 Skill 不依賴 API Key,但 Crawlee 官方文檔、Python 包、Playwright 瀏覽器依賴本身都要從外部拉取,內網環境需要先處理鏡像源。

小結

這個 Skill 的價值在於把「採集腳本」和「採集流水線」之間的工程決策顯式化:路由怎麼分、請求節奏怎麼控、數據往哪存、什麼時候用瀏覽器。配合 Crawlee 的安裝命令和模板,可以在 Python 或 Node.js 裏較快搭起一條能長期跑的採集流程。

官方地址:https://www.skillhub.cn/skills/kunlungrowth/python-node-web-crawler

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜