Scrapy 之所以常被歸類為「無法應付現代網站」,是因為它不執行 JavaScript。但這個印象其實剛好反了。Scrapy 的核心設計,本來就不是去渲染頁面;一旦你看懂它怎麼運作,就不會再把這點當成缺陷。
我自己也在一次實測裡徹底驗證了這件事。我做了一個由 JavaScript 渲染的商品目錄測試頁,把 Scrapy 指向瀏覽器會看到的那個頁面,結果只抓回 0 張商品卡。接著,我把同一隻 spider 對準那個頁面在背景中默默呼叫的 JSON 端點,卻順利拿回 8/8 筆資料,而且乾乾淨淨。相同工具、相同 session,結果卻完全相反——這兩個數字之間的差距,就是這篇評測的重點。
Scrapy 到底是什麼,又不是什麼

Scrapy 是一個用來爬取網站並擷取結構化資料的 Python 框架。這也是維護團隊在 overview docs 裡對它的定位;實際用過之後,你會發現這個說法非常精準,完全不需要再加行銷包裝。它已經成熟到成了很多 Python 開發者想到「認真做網頁爬蟲要用什麼」時的直覺答案,而它的 repo 也證明了這點:截至 2026-07-07,大約有 62,981 顆 GitHub stars(scrapy/scrapy),同一天還有 11,773 個 forks 與 590 個 open issues。它採用 BSD-3-Clause 授權,支援 Python 3.10 以上;我實測的版本是 2.17.0,而且剛好就在我測試當天早上釋出,所以這次沒有任何「其實是舊版」的疑慮。
真正把它和新一代 AI 爬蟲區隔開來的,是這條設計邏輯:Scrapy 預設只做 HTTP 請求,不開瀏覽器、不跑渲染引擎。它把 HTML 抓下來,交給 parser,再用 CSS selector 或 XPath 把欄位取出來。把這件事說成限制,只對了一半,而且忽略了它原本的設計初衷。Scrapy 的假設是:對一般的抓取工作來說,為了看一個頁面就啟動 headless Chrome,通常不是最佳解;更聰明的做法,是直接找到頁面本來就會呼叫的資料請求,直接打那個請求。
這不是我對工具的詮釋,而是官方文件明講的。官方的 dynamic content docs 直接寫得很清楚:先找出並重現底層的資料請求,只有在真的無法重現時,才考慮使用 headless browser。大多數爬蟲會先開瀏覽器,甚至根本不會想到 API;Scrapy 則把預設值整個反過來。
主要功能,以及每個設計背後的取捨
從底層來看,Scrapy 是一整套元件的組合,而且每個元件都在暗示同一件事:你是開發者,你要的是控制權,不是點一下就結束的自動化魔法。
Spiders。 你先寫一個 class,給它起始 URL,再定義一個 parse callback,讓它回傳 item 或繼續追蹤下一層連結。這比 no-code 擷取工具要多寫不少程式碼——擷取規則得自己定義——但換來的是:你可以精準控制要抓什麼、接下來要爬去哪裡。
Selectors。 解析層建立在 parsel 上,而 parsel 底層又是 lxml。CSS 與 XPath 都是第一級支援,不是後加上去的附屬功能。也正因為有 lxml 撐著,選取速度夠快,而擷取程式碼看起來也更像在表達意圖,而不是一團字串切割的混亂拼貼。
Feed exports。 只要把 spider 指向檔案,Scrapy 就會自動把 item 輸出成 JSON、JSON Lines、CSV 或 XML,完全不需要額外串接。我在測試裡跑一個靜態商品目錄 spider,就直接吐出 JSON 和 CSV,連一行匯出程式都沒寫——feed export 的功能是真的,而且確實照它說的運作。
AutoThrottle 與爬取控制。 Scrapy 的請求是透過 Twisted 非同步排程,你可以設定並發上限、下載延遲、深度限制、AutoThrottle 自動限速,以及遵守 robots.txt。這些控制項的目的,就是避免大範圍爬取最後變成一場對伺服器的暴力轟炸。
把 HTTP-only 當成優勢。 沒有瀏覽器,就代表更低記憶體、更高吞吐量,也不用去照顧渲染引擎——前提是你要的資料本來就能透過一般 HTTP 拿到。而這種情況,其實比瀏覽器優先派想像得更常見。
安裝:沒人會拿去發 IG 的依賴堆疊

安裝過程幾乎沒發生任何事,對這種規模的框架來說,反而值得特別說明。pip install Scrapy==2.17.0 在 macOS arm64 的全新 virtual environment 裡順利完成,拉下來的是 binary wheels,沒有任何編譯失敗卡關。沒什麼戲劇性——但重點就是沒有戲劇性。
不過看看實際裝了什麼,你就會知道這不是小玩具。scrapy version -v 顯示 Scrapy 2.17.0 依附在 lxml 6.1.1、Twisted 26.4.0、pyOpenSSL 26.3.0、cryptography 49.0.0 之上,另外還有 parsel、cssselect 與 tldextract。這是真正的重量級依賴組合,是一整套爬蟲框架的 footprint,不是一個單檔 HTML parser。這台機器上所有套件都有對應 wheel,所以安裝很順。換到其他環境,官方文件仍然會提醒你注意平台相容性,歷史上最容易出問題的通常是 cryptography 和 Twisted 這一段,所以如果你用的是比較冷門的平台,最好預留一點心力。這次安裝很順,但你在正式導入前,還是應該知道它本來就不是輕量級方案;你拿進來的是一個框架,而框架本來就有框架的重量。
實測:哪些地方表現穩定

安裝完成後,靜態頁面的路線非常順。完整回收,沒有漏資料。
| 測試 | 結果 | 執行時間 |
|---|---|---|
| 本機靜態商品目錄 + 分頁 | 12/12 項商品 | 0.557s |
| 靜態商品目錄 CSV 匯出 | 寫出 12 筆資料 | (同一次執行) |
| 文章擷取 | 標題 + 3/3 段內文 | 0.416s |
| 爬取圖譜,DEPTH_LIMIT=2 | 深度 0/1/2 共 11 個頁面 | 0.904s |
| 本機 500 頁面 | 成功捕捉 status 500,未當機 | 0.424s |
| Books to Scrape(公開站) | 20 筆商品 | 2.053s |
| Quotes to Scrape spider(公開站) | 12 筆 quote 資料 | 3.465s |
靜態商品目錄 spider 從第 1 頁一路走到第 2 頁,抓滿 12/12 筆預期資料,然後同一次就輸出了 JSON 和 CSV。文章測試檔則更值得看。Scrapy 不會自動幫你把頁面整理成乾淨的 Markdown;相反地,它讓你用明確的 selector 精準鎖定 article 欄位,並把導覽列與頁尾文字放到不同欄位中,所以我拿到的是 3/3 段內文,而那些模板字樣被隔離起來,沒有混進輸出內容。這就是取捨:你自己寫 selector,就能得到你想要的,其他東西不會自己跑進來。
在小規模爬取下,它的控制能力也沒掉鏈子。開啟 DEPTH_LIMIT=2、加上短下載延遲、每網域並發限制與 robots.txt 遵守後,爬取圖譜在深度 0、1、2 共走了 11 個頁面,而且深度計算正常運作。失敗處理同樣很平穩。那個刻意設計的 500 頁面,透過 handle_httpstatus_list 被包成一個結構化 item,狀態碼 500 正常回傳,沒有例外、沒有整個 run 掉下來。Scrapy 把錯誤狀態當作你要在 spider 邏輯裡處理的資料,而不是一個會把整個爬取流程炸掉的驚喜。
實測:JavaScript 的牆,以及旁邊那扇門

接下來就是這篇評測真正的核心結果。
我把 Scrapy 的 HTTP fetcher 指向一個由 JavaScript 渲染的商品目錄測試頁。它下載了原始 HTML,找到 0 個 .product-card 節點,然後就繼續往下走——因為它根本沒有執行會把那些卡片畫出來的 script。公開的 Quotes to Scrape JS page 也講了同樣的故事:0 個已渲染的 quote 節點。如果你只做到這裡,大概會直接把 Scrapy 打成「這年頭根本不能用」的工具。
但別停在這裡。那個 JS 商品目錄,其實是在背景透過 JSON API 填資料,很多網站都是這種做法。我把同一隻 Scrapy spider 指向那個端點,結果在 0.416s 內抓回 8/8 筆商品——不用瀏覽器、不用渲染,只是直接請求頁面本來就在呼叫的 URL,然後解析回來的 JSON。
這種左右並列的結果,正好把「重現請求」這個理念說得很清楚。你看到的渲染頁面只是煙霧彈;真正的資料一直都躲在 API 後面,而 Scrapy 的設計就是要你直接打那個 API,而不是花成本讓 headless browser 在那裡等頁面慢慢拼好。這樣更快、更輕,也更不容易壞——API 合約通常比前端 DOM 穩定得多。只是代價是:這是手動工作。你得自己打開 network tab、找出那個 request,然後把它的 headers 和 params 重現出來。Scrapy 不會幫你自動找 API;它只是在你已經找到之後,讓你呼叫它變得非常簡單。
另外也要把兩個邊界講清楚。若真的沒有任何可重現的底層請求——也就是資料完全由 client-side rendering 組出來,背後沒有 API——那麼 Scrapy 就需要你自己接上一個 headless browser,我在這次測試裡沒有驗證那條路徑。還有,上面的所有測試都只是在小型 fixture 和公開 demo 頁面上完成的。我沒有跑 100 到 1,000 頁的大型爬取,所以這次不對記憶體、吞吐量或 retry 行為在大規模情境下做任何保證——非同步核心與爬取控制確實很有說服力,但「有跡象」不等於「已量測」。
優點與缺點
優點:
- HTTP-only 設計速度快、負擔輕——靜態頁面 12/12 在大約半秒內抓完,JSON API 也能在 0.416s 內拿到 8/8,完全沒有瀏覽器開銷。
- 「重現請求」這個思路真的有效:一個 JS 頁面回傳 0 筆,但透過後端 API 成功拿到全部 8 筆。
- 由
lxml驅動的 CSS 與 XPath selector,讓擷取程式碼既清楚又快速。 - 可直接輸出 JSON / CSV / XML,不需要額外寫匯出流程。
- 錯誤處理明確:500 狀態會以可捕捉的狀態回來,而不是直接把程序弄掛。
- 成熟的爬取控制:並發、延遲、深度限制、AutoThrottle、robots.txt。
- BSD-3-Clause 授權,且在現代環境中安裝順利。
缺點:
- 設計上就不渲染 JavaScript——在 client-side 渲染頁面上,找不到 API 之前就會是 0 個節點。
- 找底層請求要靠人工,Scrapy 不會直接幫你指出端點。
- 依賴堆疊不小(Twisted、lxml、cryptography、pyOpenSSL、parsel、tldextract)——這次很順,但在某些特殊平台上,歷來就是摩擦來源。
- 需要寫的程式比 no-code 或自動擷取工具多;spider 得自己寫、自己維護。
- 這次只測了小型 fixture 和 demo 網站,沒有測大型爬取;大規模可靠性還沒有被這一輪驗證。
適合誰,不適合誰

Scrapy 適合那些想要程式碼層級控制、思考方式是以 request 為主而不是以頁面為主的開發者。如果你遇到一個速度很慢的 JavaScript 網站,第一個反應是「這裡面應該有 API 才對」,那這個工具就是照著你的直覺設計的。它特別適合會寫 selector、會看 network tab、而且願意從頭到尾自己掌握擷取邏輯的人。對靜態網站、分頁型商品目錄,以及任何有可發現 JSON 端點的資料來源,它都又快又準。
如果你不想花時間寫和維護 spider 程式碼,或者你的目標頁面完全靠 client-side rendering,背後又沒有可重現的 request,而你也不想自己額外接 headless browser,那就該直接略過 Scrapy,或者至少搭配別的工具一起用。還有,如果你期待的是「貼上一個 URL,立刻得到乾淨的結構化輸出,而且完全不用自己定義擷取規則」,那本來就不是 Scrapy 的任務,它也從來沒有假裝自己能做到這件事。
替代方案,以及 Thunderbit 的定位
先想清楚你要承擔的是什麼:這是一個免費、開源、需要你自己執行與維護的框架。你要自己管理 spiders、依賴堆疊,以及逐站找出資料請求的工作。作為交換,你不用為每次請求付費,所有東西都能留在自己手上,而且控制權完全在你。對很多團隊來說,這正是正確選擇,而這篇評測也不是要把任何人勸退。
真正的取捨,其實卡在渲染與變動這件事上,而 Scrapy 的答案是:由你自己去解決。你要自己找 API、自己重現請求,遇到沒有 API 的情況,再自己把 browser 接進來。相對地,託管式的 AI 擷取 API 可以把這一層從你的工作裡拿掉。對技術讀者來說,Thunderbit 的開發者工具鏈就位在這個位置——它提供的是 AI 擷取 API、MCP server 和 CLI,不是業務與營運團隊在用的瀏覽器擴充功能。POST /distill 可以把頁面轉成乾淨、可供 LLM 使用的 Markdown;POST /extract 能依照你定義的 schema 回傳結構化 JSON;而且兩者都能在伺服器端處理 JavaScript 渲染、反爬與動態內容——包括 Scrapy 需要你自己去找 browser 的那種 client-rendered 場景。它還有一個給 AI agents 與 coding assistants 用的 MCP server(附帶免費的 thunderbit_suggest_fields,可以在你花錢前先估算頁面欄位),以及可透過 npx @thunderbit/thunderbit-cli 使用的 CLI,方便你在終端機、CI 或 cron 裡工作。
差別不在品質,而在責任歸屬。Scrapy 是一個非常明確的工程框架:spider、pipeline、JS 策略都由你維護,你換來的是零單次呼叫成本下的完全控制。Thunderbit 的工具鏈則是把渲染與擷取層交給託管服務處理,讓你省去在 network tab 裡挖半天的工作,改成按次計費。如果你是小規模、程式先行,而且喜歡把每一步都握在自己手裡,那 Scrapy 的控制感更合適。若你要橫跨上百個網站,而且不想每個站都自己重現一次請求,那託管方案就能直接移除這整類工作。
如果你想看更大的市場比較,這些基準測試文章也可以一起參考:完整的開源爬蟲比較、Colly 無瀏覽器 Go 爬蟲評測,以及 Scrapling 的自適應 selector 評測。
結論
Scrapy 值不值得用?值得——如果你是想要控制權的開發者,而且你認同它的世界觀:不要渲染頁面,去找頁面背後的請求。在這次測試裡,這套哲學完全如實發揮。JavaScript 商品目錄讓 HTTP fetcher 只看到 0 張卡片;餵它資料的 JSON API,卻讓同一隻 spider 一口氣拿到全部 8 筆。靜態抽取做到 12/12,文章 selector 保住了 3/3 段內文不被模板字樣污染,爬取圖譜在 11 個頁面內遵守深度限制,而 500 狀態也只是被正常處理,而不是讓程式崩潰。
不過也要把這些結論放在正確尺度上看。Scrapy 不會渲染 JavaScript,也不會替你找 API——這份直覺得靠你自己建立。它的依賴堆疊有框架的份量,雖然在這次環境裡很順,但在特殊平台上仍然可能出問題。而我這次測的是 fixture 和 demo 頁,不是上千頁的大型爬取,所以對規模表現只能說「前景不錯」,還不能說已經被證實。在這些前提之內,Scrapy 是最忠於一個安靜但激進理念的工具:通往網頁資料最快的路,往往根本不是走進頁面本身。
試用 Thunderbit 進行網頁資料擷取 Get Started Free
常見問題
Scrapy 可以爬 JavaScript 渲染的頁面嗎? 預設的 HTTP fetcher 不行——我在 JavaScript 測試頁和公開的 Quotes JS 頁上都只拿到 0 個節點,因為它只下載 HTML,不會執行瀏覽器。Scrapy 預期的做法,是找出頁面背後真正呼叫的資料請求,然後直接打那個請求;在我的測試中,那個 JS 商品目錄背後的 JSON API 成功吐出全部 8 筆。如果頁面根本沒有可重現的請求,那就得由你自己接上 headless browser。
「重現請求」到底是什麼意思? 多數動態頁面會先在背景向 JSON API 取資料,再由前端把內容渲染出來。與其開瀏覽器看整個過程,你可以直接打開 network tab,找到那個 API 呼叫,然後讓 Scrapy 直接對準它。這比渲染頁面更快也更穩——API 合約通常比 DOM 更不容易壞——但這是手動作業,Scrapy 不會自己幫你找端點。
Scrapy 安裝困難嗎?
對我來說很順——在 macOS 的全新 venv 裡執行 pip install Scrapy==2.17.0,完全沒有編譯錯誤,而且是透過 binary wheels 完成。不過它會拉進一大串依賴(Twisted、lxml、cryptography、pyOpenSSL、parsel、tldextract),而且官方文件也仍然提醒你某些系統可能會有平台相依的摩擦,所以如果你用的是比較特殊的環境,最好把這點納入預算。
Scrapy 支援哪些輸出格式? Feed exports 內建支援 JSON、JSON Lines、CSV 與 XML——只要把 spider 指向檔案,它就會自動序列化你的 item,不用額外寫程式。在我的測試裡,同一隻 spider 一次就輸出了 JSON 和 CSV。要注意的是,它匯出的是你選定的欄位,不會自動把頁面整理成 Markdown。
Scrapy 可以商業使用嗎? 可以,它採用 BSD-3-Clause 授權,屬於寬鬆且對商業友善的類型。當然,在實際建置前,還是建議你到 repo 再確認一次目前的授權條款,並且對 user-agent、proxy 與 rate limit 的設定保持負責任的態度——有能力不等於有權利。


