Scrapling:用自適應選擇器把 Web Scraping 從一次性腳本升級成可持續爬蟲
Scrapling 是一個以 Python 打造的自適應 Web Scraping framework,從 HTML parser、瀏覽器 fetcher 到可暫停續跑的 spider 與 MCP server 都整合在同一套 API。本文拆解它如何面對網站結構變動,並用可執行範例建立一個從單頁擷取到並行爬取的實作流程。
Scrapling:用自適應選擇器把 Web Scraping 從一次性腳本升級成可持續爬蟲
很多爬蟲專案不是寫不出第一版,而是網站改版後,CSS selector、DOM 層級與反爬策略一起變動,原本能跑的腳本很快變成維護負擔。Scrapling 的切入點不是再包一層 HTTP client,而是把 parser、fetcher 與 crawler 放進同一套可組合的 Python framework,並讓選取器能在頁面結構變動後嘗試找回原本的元素。
本文以官方 repository 與 pyproject.toml 的目前內容為準,拆解 Scrapling 的核心設計,並用幾個可直接改寫成專案的範例,說明它適合哪些資料擷取工作。
先看專案定位
Scrapling(GitHub)是 BSD-3-Clause 授權的 Python Web Scraping framework,官方套件目前要求 Python 3.10 以上,pyproject.toml 的版本為 0.4.12。截至 2026 年 8 月 9 日,repository 顯示超過 73,000 顆 stars,最近一次 push 在 2026 年 8 月 8 日,符合「高星且持續更新」的實作型開源專案條件。
它把功能分成四個層次:
- Parser:解析 HTML、CSS/XPath 選擇、文字搜尋與相似元素尋找。
- Fetcher:從一般 HTTP request,到可處理 JavaScript 與 stealth browser 的不同抓取路徑。
- Spider:提供並行、節流、重試、pause/resume 與串流結果的爬蟲框架。
- 介面整合:CLI、Web Scraping shell,以及可讓 AI agent 呼叫的 MCP server。
這種分層讓你可以從一個 fetch 呼叫開始,之後再逐步升級成有 session、proxy、並行度與結果輸出的 crawler,而不必整套換框架。
安裝策略:先從 parser 開始
官方把瀏覽器與命令列能力拆成 optional dependencies,這是 Scrapling 很重要的使用邊界。只需要解析已經拿到的 HTML 時,安裝核心套件即可;要使用 fetcher、spider 或瀏覽器自動化,則要安裝對應 extras。
若用 uv 管理專案,可以這樣開始:
uv init scrapling-demo
cd scrapling-demo
uv add "scrapling[fetchers]"
uv run scrapling install若需要 MCP server 或完整 shell 功能,可以改用:
uv add "scrapling[all]"
uv run scrapling installscrapling install 會安裝瀏覽器及其相關依賴。只執行 uv add scrapling 並直接 import scrapling.fetchers,不會得到完整的瀏覽器能力,這是新手最容易踩到的安裝落差。
核心差異:把選擇器變成可學習的定位
傳統爬蟲常把 selector 寫死:
product = page.css(".product-card h2::text").get()只要 .product-card 改成 .item-card,程式就會回傳空值。Scrapling 支援先在穩定版本的頁面上保存元素特徵,再在後續頁面使用 adaptive selection 嘗試找回相同語意的節點:
from scrapling.fetchers import StealthyFetcher
StealthyFetcher.adaptive = True
page = StealthyFetcher.fetch(
"https://example.com/products",
headless=True,
network_idle=True,
)
# 第一次抓取時保存元素特徵
products = page.css(".product-card", auto_save=True)
# 網站改版後,改用 adaptive=True 找回相似元素
products = page.css(".product-card", adaptive=True)
for product in products:
print(product.css("h2::text").get())這個機制不是保證任何改版都能自動修復,也不是取代測試。它的價值在於把「selector 失效後全部人工重寫」變成「先嘗試根據元素特徵恢復,再由測試或監控確認結果」。對長期跑的資料管線來說,這個容錯層比單純追求更短的 CSS selector 更有用。
Fetcher:依頁面難度選擇抓取路徑
Scrapling 沒有把所有網站都當成同一種 request。官方 API 提供不同強度的 fetcher:
| 場景 | 建議入口 | 重點 | | --- | --- | --- | | 靜態 HTML、追求速度 | Fetcher | 一般 HTTP、瀏覽器 impersonation 與 HTTP/3 支援 | | 需要 JavaScript 執行 | DynamicFetcher | 透過 Playwright/Chrome 載入動態頁面 | | 需要更完整的 stealth 能力 | StealthyFetcher | fingerprint spoofing、session 與反自動化處理 | | 非同步工作流 | AsyncFetcher | 配合 async pipeline 使用 |
實務上可以先用最便宜的 HTTP 路徑;只有在 HTML 不完整、需要登入狀態或頁面由 JavaScript 產生時,才升級到 browser fetcher。這能同時控制執行時間、記憶體與被封鎖的風險。
另外,fetcher 支援 session、proxy rotation、remote browser、XHR capture 與 ad/domain blocking。這些能力適合資料來源較複雜的工作,但也代表你應該把請求速率、授權、robots.txt 與網站服務條款納入設計,而不是把「能抓到」當成「可以任意抓」。
Spider:從單頁腳本走向可恢復的 crawl
當資料量增加,真正難處通常不是 selector,而是重試、節流、斷線恢復與結果交付。Scrapling 的 spider API 以 async parse callback 為核心:
from scrapling.spiders import Spider, Response
class ProductSpider(Spider):
name = "products"
start_urls = ["https://example.com/"]
async def parse(self, response: Response):
for item in response.css(".product"):
yield {
"title": item.css("h2::text").get(),
"url": item.css("a::attr(href)").get(),
}
ProductSpider().start()官方 spider 層提供 configurable concurrency、per-domain throttling、blocked request detection、AutoThrottle、pause/resume、streaming,以及 JSON/JSONL/CSV/XML 匯出。也就是說,這段 callback 可以自然地往生產環境擴充,而不是把所有控制流程塞進一個巨大 while 迴圈。
建議的生產化順序是:
- 先用 development mode 快取 response,反覆調整
parse()而不重複打目標站。 - 開啟 robots.txt 遵循與合理的 domain concurrency。
- 對 blocked response、空結果與 schema 變更加上明確監控。
- 使用 pause/resume 及串流輸出,把長時間任務和下游資料管線解耦。
CLI 與 MCP:讓工具進入自動化工作流
不想每次都寫 Python 時,可以使用 CLI:
uv run scrapling shell
uv run scrapling extract get \
'https://example.com' \
content.md \
--css-selector '#content' \
--impersonate 'chrome'如果團隊正在建置 AI agent,scrapling[ai] 會提供 MCP server 所需依賴,讓 agent 能以工具方式取得網頁內容。這裡的重點不是「讓模型自由瀏覽所有網站」,而是把 fetch、extract、輸出格式與權限界線包成受控工具,並在 server 端留下請求紀錄與限制。
效能數字要怎麼看
官方 README 的 parser benchmark 顯示,在 5,000 個巢狀元素的文字擷取測試中,Scrapling 平均 1.98 ms,與 Parsel/Scrapy 的 1.99 ms 接近;在元素相似度與文字搜尋測試中,README 列出的平均時間為 2.29 ms。這些是 repository 作者提供、由 benchmarks.py 定義的特定基準,不應直接解讀成所有網站與所有抓取路徑都會快上相同倍數。
真正選型時,應把 parser benchmark、browser 啟動成本、proxy、網路延遲、目標站反應與資料清洗時間分開量測。Scrapling 的合理賣點是把穩定性與功能整合在一起,而不是一張脫離情境的速度排行榜。
適合與不適合的工作
適合:
- 需要長期維護、網站結構可能變動的資料擷取。
- 同一個專案同時包含靜態頁、動態頁與需要 session 的頁面。
- 想從一次性腳本逐步升級到可重試、可恢復的 crawl。
- 想把受控的網頁擷取能力接到 CLI、MCP 或 AI agent workflow。
不適合直接套用:
- 只需要一次性下載單一公開檔案的任務;一般 HTTP client 可能更簡單。
- 對瀏覽器依賴、反自動化處理與執行環境極度敏感的 serverless function。
- 需要保證完全繞過所有反爬機制的情境;沒有任何工具能替代合法授權、流量治理與來源協議。
結論:它解決的是維護成本
Scrapling 值得注意,不是因為它把 Web Scraping 包裝成另一個更大的 API,而是因為它把爬蟲的三個生命週期放在同一個設計裡:先抓到頁面,再用能面對改版的定位方式取資料,最後以可恢復的 spider 把工作跑長。CLI 與 MCP 則讓同一套能力能接到更大的自動化系統。
如果你的痛點是「selector 每次改版都要重寫」或「爬蟲一上線就開始處理重試與斷線」,Scrapling 是值得做小型 proof of concept 的候選。建議先選一個有測試資料的來源,記錄 selector 恢復率、空結果率、單頁延遲與瀏覽器資源成本,再決定是否把它推進正式資料管線。
使用 Web Scraping 前,請確認資料來源的授權、網站條款、robots.txt、個資與速率限制。Scrapling 官方也明確提醒使用者遵守當地與國際資料擷取及隱私法律。