Botasaurus 是 Omkar Cloud 推出的 Python 網頁爬蟲框架,主打一站式建構爬蟲方案。你只要寫一個普通函式,再加上 @browser、@request 或 @task 裝飾器,框架就會自動幫你接上瀏覽器驅動、類瀏覽器 HTTP 客戶端、快取、平行處理,以及多種格式輸出。它本質上是一個 meta-package,而這正是重點:pip install botasaurus 並不是把單一套件裝進環境裡,而是會組出一組第一方 wheel,再加上一整棵龐大的轉依賴樹。這個機械層面的細節,反而成了我能誠實量測到的最有意思的地方。
Botasaurus 的行銷重點放在 anti-detection,而這正是這篇評測刻意不碰的面向。我整理的是框架本身:安裝了什麼、匯入了什麼、有哪些方法、體積多大、採用什麼授權,而不是把它拿去對打任何真實防護機制。下面所有的體積與匯入數字,都來自 pip、python -c "import ...",以及對已建立但從未被要求抓取頁面的類別做 introspection;為了產出這些數據,我沒有啟動瀏覽器。後來我確實有啟動瀏覽器,但只連到我自己寫、自己在 127.0.0.1 上提供的頁面,看看驅動程式會怎麼宣告自己,以及它能不能從一個靠 JavaScript 自己生成內容的頁面抓出資料。整個過程沒有接觸任何真實網站,沒有連到或量測任何 anti-bot 服務,也沒有碰到 CAPTCHA。對真實網站的效果不在本次範圍內;我寧可先講清楚,也不要暗示一個我根本沒跑過的 benchmark。
在這條界線畫好之後,重點結果其實很單純,也算溫和:一次乾淨安裝會產生一個 122.3 MB 的 site-packages 目錄,涵蓋 44 個套件;而整個系統核心的瀏覽器驅動大約只有 4 MB。框架之所以重,不是因為驅動本身重,而是因為「一站式」意味著它把 numpy、lxml、gevent,以及另外十多個為了抓 HTML 而帶進來的工具一起裝上了。第二個結果則是那種常被拿來當優點引用、但其實不該太當真的數字:import botasaurus 只花 0.08 ms,看起來像超輕量框架,實際上只是門面很空。
Botasaurus 到底是什麼
Botasaurus——GitHub 上的 omkarcloud/botasaurus,我在 2026 年 7 月 14 日抓取 metadata 時,它有 5,561 顆星、486 個 forks、58 個 open issues——是一個 Python 框架,不是單一用途的小函式庫。我實測的版本是上層 meta-package botasaurus 4.0.97,以及底層引擎 botasaurus-driver 4.0.92。meta-package 的 requires-python >=3.7(driver 則是 >=3.5),PyPI 的 classifier 只宣告支援到 3.11。不過它在我機器上的 Python 3.14.2 可以安裝成功,且通過 import smoke test。這只能證明這次安裝沒問題,不代表所有功能都能在所有環境中相容。
先把分類釐清,因為這會決定什麼叫「好」。Botasaurus 屬於 framework 這一端,和 Scrapy 與 Crawlee 同一個領域:你要接受它的結構、裝飾器與約定,它則幫你把底層雜務都處理掉。這和像 nodriver 這種專注型 driver 很不一樣,後者只提供 Chrome DevTools Protocol 連線,剩下的就交給你自己。Botasaurus 雖然包了一個 driver(也就是 botasaurus-driver),但外面再套了 task runner、快取層、輸出序列化器,以及 request client。你買的不是單純驅動,而是一個帶有明確觀點的工作流程,驅動只是其中一部分。
三個裝飾器幾乎就是整個設計的縮影,而且這三個入口都是真的存在——我確認 botasaurus.browser.browser、botasaurus.request.request 與 botasaurus.task.task 都能匯入。@browser 會讓你的函式跑在擬人化的瀏覽器驅動上。@request 則是跑在一個看起來像瀏覽器的輕量 HTTP client 上。@task 則是給不屬於前兩者的情境使用的通用包裝器。加上裝飾器之後,Botasaurus 會補齊周邊機制:平行執行、驅動重用、結果快取,以及 JSON、CSV、Excel、HTML 的寫出器。這個想法很完整。你是否需要這麼多框架包在爬蟲外面,才是問題的核心——而這是偏好問題,不是缺陷。
我的結論,以及這篇評測的邊界
Botasaurus 是一個稱職、結構清楚,而且確實把 framework 該做的事做好的工具:讓常見情境寫得更短。裝飾器模型設計乾淨,MIT 授權也確實大方。如果我在評 API 介面的易用性,它的表現是好的。
但我一直繞回來的點是,這個框架主打的賣點——anti-detection——正是負責任的評測不能隨便評論的部分,除非把它丟到某個人的生產防護機制前面。這個 driver 的確提供了一組明確標榜 anti-detection 的 API;我確認過這些方法存在,但沒有去實測它們對任何目標的行為。這就是我能說的全部。我沒有把它丟到受保護網站前,沒有量成功率,沒有逆向任何機制,也不會用措辭去暗示這三件事。這些方法確實在 class 裡。它們在真實世界做了什麼,則是另一篇評測的範圍,而不是這篇。
接下來的內容,是能力、安裝、資源與授權的清單,以及我在自己控制的頁面上看到的 driver 行為——這個敘述比多數對這類工具的評測都更窄,而這種窄,正是重點。
它會怎麼宣告自己

有一個問題你不用碰真實防護系統就能回答:當 Botasaurus 驅動瀏覽器時,這個瀏覽器會對它正在看的頁面透露些什麼?我寫了一個頁面來讀取最明顯的資訊——navigator.webdriver、user-agent、platform、languages、plugin 與 hardware 數量、window.chrome 的形狀、Permissions API 的回應、window 與 screen 幾何資訊——把它放在 127.0.0.1 上,然後拿四個 stack 去跑:Botasaurus、nodriver,以及原生 Playwright 與原生 Puppeteer 當控制組。四者都驅動 同一個 Chrome build(Chrome for Testing 151.0.7922.10),所以有差異的地方,就是 library 本身,不是瀏覽器。headless 與 headed 都跑了,每個三次。下面每個值在三次中都一致。
| Stack | 模式 | navigator.webdriver | User-agent token | navigator.languages |
|---|---|---|---|---|
| Botasaurus 4.0.92 | headless | false | HeadlessChrome/151.0.0.0 | ["en-US"] |
| Botasaurus 4.0.92 | headed | false | Chrome/151.0.0.0 | ["en-US"] |
| nodriver 0.50.3 | headless / headed | false | HeadlessChrome/151 / Chrome/151 | ["en-US"] |
| Playwright 1.56.0 | headless / headed | true | HeadlessChrome/151 / Chrome/151 | ["en-US","en"] |
| Puppeteer 24.16.0 | headless / headed | true | HeadlessChrome/151 / Chrome/151 | ["en-US"] |
差異其實取決於你拿哪個控制組比較。對原生 Puppeteer 來說,Botasaurus 會把 navigator.webdriver 改成 false;語言清單與零尺寸的視窗幾何資訊相同,而 user-agent 只是在版本格式上略有不同。對原生 Playwright 來說,觀察到的差異還包含語言清單與視窗幾何。對 nodriver,這裡列出的 boolean 與 languages 也相同,只有 user-agent 格式稍有不同。這些都是預設揭露資訊的觀察,不是 anti-detection 分數。
還有兩個細節,比單純看到 false 更有意思。第一個是這個值是怎麼來的。四個 stack 裡,這個 property 都還是 browser 原生的 Navigator.prototype getter——function get webdriver() { [native code] }——不是塞在 instance 上的 own-property,也不是被替換過的函式。也就是說,Botasaurus 並不是在頁面載入後改寫這個 property;值是在瀏覽器啟動時就決定了,而 property 本身沒有被動到。
第二個細節,則直接戳到行銷說法的核心。在 headless 模式下,Botasaurus 的 user-agent 仍然會明確顯示 HeadlessChrome/151.0.0.0——和原生 Puppeteer 一樣,和原生 Playwright 也一樣。切換到 headed 後,則變成 Chrome/151.0.0.0,同樣一致。Driver 建構子確實有 user_agent 參數,所以你只要多傳一個 keyword argument 就能設定,但預設設定並沒有掩蓋瀏覽器自我識別最著名的那串字。
其他幾乎所有值在四個 stack 間都相同,這件事值得直說,因為它把故事範圍縮小了——下面這些屬性,在 Botasaurus、nodriver、Playwright 和 Puppeteer 上讀到的結果都一樣:
| 屬性 | 四個 stack 都相同的值 |
|---|---|
platform | MacIntel |
vendor | Google Inc. |
| Plugins | 5 |
| MIME types | 2 |
pdfViewerEnabled | true |
| 邏輯核心數 | 12 |
| 回報的裝置記憶體 | 16 GB |
| Touch points | 0 |
window.chrome | 存在,且有 app/csi/loadTimes,但沒有 runtime |
| WebGL renderer 字串 | 四者完全一致 |
以前常見的老梗——Permissions API 和 Notification.permission 彼此矛盾——在這裡完全沒出現;四者都一致回報 default 與 prompt。我也掃過 document 和 window,確認沒有老舊 WebDriver stack 常留下的 cdc_ 類痕跡:四者都沒有。
部署前還有一件事值得知道:即使它有 122 MB,Botasaurus 本身也不會附帶或下載瀏覽器。find_chrome_executable() 會解析成你機器上原本已安裝的 Chrome——在我的機器上是 /Applications/Google Chrome.app,版本 150.0.7871.187——而 user-agent 也會揭露這個版本。你的環境中裝了哪個 Chrome,對外就會宣告哪個版本;對一個風格如此鮮明的框架來說,這個預設反而出奇地不帶立場。
要說清楚它是什麼、不是什麼。這是一份關於自動化 stack 在沒人要求它隱藏時會透露什麼的紀錄——如果你站在防守方,這很有用;如果你想知道自己的工具會對外廣播什麼,也很有用。但這不是在衡量這些資訊對某個特定服務是否重要。我沒有測這件事,所以上面的任何一列都不該被解讀成某種結果暗示。
這個 fixture 上更寬容的預設讀取結果
會不會宣告自己是一回事;能不能拿回正確的 HTML 才是重點。我把 Botasaurus 丟到這個 benchmark repo 其他工具也使用的三類內容 fixture 上,因此數字可以跟整個系列對齊。這個頁面有三種內容:A 是靜態連結,標記直接寫在伺服端送出的 bytes 裡;B 是在 parse 過程中由 inline script 建立的節點,它的標記與 URL 都是由片段組合而成,只有真的執行 JavaScript 才看得到;C 則是在 load event 後 800 ms 才注入的節點,也是同樣方式組成。Class C 是最具對抗性的那個——如果在 load event 時讀取,根本看不到它。
| Stack | 預設讀取 | 額外等待後 |
|---|---|---|
| Botasaurus 4.0.92 | 3 個中的 2 個(A + B,漏掉 C) | 3 個中的 3 個 |
| nodriver 0.50.3 | 2 of 3 | 3 of 3 |
| Playwright 1.56.0 | 2 of 3 | 3 of 3 |
| Puppeteer 24.16.0 | 2 of 3 | 3 of 3 |
Botasaurus 的結果和那些大牌工具落在同一區間。driver.get() 接著直接讀 driver.page_html,得到的是 load 時點的快照:它確實有正確執行 JavaScript——class B 就證明了這點,因為 class B 在伺服端送出的 bytes 裡根本不存在——但對於 800 ms 才出現的內容,它還是會漏掉 class C。加上 driver.wait_for_element("#delayed-injected") 之後,就能拿到全部三個。這個結果在三次重複與整套測試的三次完整執行中都一致,沒有 flake。
有趣的地方出現在你把注入延遲拉開,去看每個 stack 的預設讀取何時開始失手:
| Class-C 注入時間 | Botasaurus | nodriver | Playwright | Puppeteer |
|---|---|---|---|---|
| 0 ms | 找到 | 找到 | 找到 | 找到 |
| 100 ms | 找到 | — | — | — |
| 200 ms | 找到 | — | — | — |
| 300 ms | 找到 | — | — | — |
| 400 ms 以上 | — | — | — | — |
其他 stack 只要在 load 後 100 ms 或更晚才注入,就會立刻漏掉 class C。Botasaurus 到 300 ms 還抓得到,直到 400 ms 才放棄。這就是 framework 風格的體現,而原因也寫在 constructor 裡:wait_for_complete_page_load=True 是預設值,所以 get() 回來的時間,會比單純等 load event 更晚。實際上,它的預設讀取在 wall clock 上會多花 401–431 ms,而 nodriver 是 119–129 ms,Puppeteer 則是 125–171 ms。
在這個本地 delayed-injection fixture 上,代價大約是每次 navigation 多出 250 ms,換來的是預設快照更晚,於是這次能抓到 load 後 300 ms 內注入的內容;但這不代表 Botasaurus 在所有網站上都更準。如果你寫的是沒有明確等待條件的快速爬蟲,這個緩衝區確實可能避免漏掉晚到的節點;但如果你的導航量很大,或你本來就已經在等特定條件,這就只是額外成本。
再看兩個規模上的 timing。把瀏覽器啟動起來時,Botasaurus 幾乎和 nodriver、Puppeteer 持平,並明顯慢於 Playwright:
| Stack | 瀏覽器啟動時間(跨多次執行) |
|---|---|
| Botasaurus 4.0.92 | 986–1151 ms |
| nodriver 0.50.3 | 910–1583 ms |
| Puppeteer 24.16.0 | 969–1008 ms |
| Playwright 1.56.0 | 282–365 ms |
而 wait_for_element() 在延遲 300 ms 以內幾乎不增加成本——因為 get() 本來就已經晚於注入完成——接著在 400–800 ms 時會跳到約 1.42 s,在 1500 ms 時則約 2.43 s。
122 MB 這個問題:meta-package 到底裝了什麼

下面這組算式最有用,所以我直接給你。把一個全新的 virtual environment 裡乾淨執行 pip install botasaurus,最後得到的是一棵 122.3 MB 的 site-packages 樹,包含 44 個 dist-info 套件。把 pip 本身扣掉(10.9 MB,那是 venv 額外開銷,不是 Botasaurus 自己要求的)之後,框架與依賴大約合計 111 MB。真正負責瀏覽器自動化的驅動程式本體,大約只有 4 MB。所以差不多有 107 MB,是這個 meta-package 認為你需要的其他東西。
這些空間都花在哪裡?單看前五個最重的轉依賴,就已經佔掉大部分了(每一列都是 artifacts/raw/runs/resource_baseline.run1.json 裡的 install_footprint.heaviest_deps_mb 項目;總和是我自己加的,不是檔案欄位):
| 套件 | 磁碟占用 |
|---|---|
| numpy | 30.9 MB |
| lxml | 19.2 MB |
| botasaurus_requests | 12.6 MB |
| gevent | 11.3 MB |
| pygments | 8.4 MB |
| 五個套件合計 | 82.4 MB(30.9 + 19.2 + 12.6 + 11.3 + 8.4) |
單一最大的項目是 numpy,這點讓我挑了一下眉——那是一個線性代數函式庫,竟然被放進一個主要工作是抓取與解析網頁的工具裡。這不算錯,框架本來就會累積各種輔助依賴,而且依賴樹裡顯然有地方想做陣列運算;只是這麼多機器,用在這件差事上還是偏豪華。
如果拿規模來比,專注型 driver nodriver 在同一台機器上大約是 17.2 MB、6 個套件,等於大約輕了 7 倍。(這個數字不是這次套件的結果,而是來自 nodriver 自己的 artifacts/raw/runs/resource_baseline.run1.json 裡的 install_footprint.site_packages_total_mb,是在同一主機上另外一次分散執行中量到的;122.3 ÷ 17.2 = 7.1。)這兩個數字都不是缺陷,也不是能力排名;它們只是「內建全餐」的框架,和專注型 driver 之間的機械成本差異。在 container 裡,量到的 site-packages footprint 會算進應用層;它不是完整 image size,而這次也沒有量 build 或 cold-deploy 時間。
還有一個 footprint 小插曲:在 introspection 過程中,第一次使用 from botasaurus.request import request 會觸發一次約 12.8 MB 的下載。這次捕捉到的 run 沒有把 artifact 與目的地記錄得足夠清楚,所以我不會把這個數字當成穩定的安裝體積增加。但它確實顯示,這段程式路徑第一次使用時可能需要網路連線,這一點在你自己的映像檔裡,尤其是要做離線或 air-gapped 部署前,最好先重現一次。
那個會說謊的 import 數字
冷啟動的 import 時間,正是這組數據最容易被誤讀的地方。以七次全新的 subprocess import 來看,最上層的 import botasaurus 中位數只有 0.08 ms。如果只看這個數字,會以為它是這個類別裡最輕的框架。
其實不是。它之所以快,是因為上層幾乎沒有東西。頂層 botasaurus 套件沒有 __version__,公開命名空間也幾乎是空的——匯入它幾乎不做任何事,因為它本來就幾乎什麼都不含。對 CLI 工具或 serverless cold start 來說,你真正需要在意的,是 engine 的 import:from botasaurus_driver import Driver 大約要 135 ms,而且在多次執行中穩定到只差幾毫秒。這才是你在抓任何一個頁面之前,先得付出的固定成本。再加上 driver 模組一旦匯入後,resident memory 會落在約 29–30 MB——而且這還是在 Chrome process 尚未啟動前。等你真的啟動瀏覽器,記憶體會大幅上升;這次我沒有量一個正在跑的瀏覽器記憶體,所以不會硬塞一個數字給你。
結論很簡單,但很重要:import botasaurus 很快,並不是因為 framework 很省,而是因為頂層包是空的。如果你在估算 cold start,請量你真正會依賴的那個 import。
API 形狀:近乎空殼門面後面的 99 個方法

引擎的 Driver class 暴露了 99 個公開方法——涵蓋導航、元素查詢、cookie 與 local storage、滑鼠與鍵盤操作、截圖、分頁管理、CDP passthrough,以及檔案上傳等廣泛面向。constructor 有 18 個參數,基本上已經把可調整的面向都畫出來了:headless、proxy、profile、tiny_profile、block_images、block_images_and_css、wait_for_complete_page_load、chrome_executable_path、extensions、arguments、user_agent、window_size、lang,以及其他幾個。從建立實例時的 API 來看,它涵蓋了大多數 browser wrapper 會提供的控制項。
真正的小陷阱在最上層,而且是無害但真實存在的。import botasaurus 會得到一個幾乎空白的 namespace——沒有 __version__,頂層公開名稱也幾乎為零。你真正會用到的東西都在子模組裡:from botasaurus.browser import browser, Driver、from botasaurus.request import request、from botasaurus.task import task。如果你想找 botasaurus.__version__ 來記錄你跑的是哪個版本,你會找不到;你得改用 importlib.metadata。這不是 bug,只是不太像多數 Python 開發者直覺會期待的結構;先知道這件事,可以幫你少花五分鐘在第一天抓頭。
關於前面提到的那些方法,還有一個與文件位置相關、但仍在我這條邊界內的觀察:在那些帶有 anti-detection 命名的方法裡,只有 2 個在程式碼內帶有 docstring。其餘方法只靠名字自我說明,細部說明則放在外部文件網站,而不是安裝後的原始碼裡。這是文件放置位置的說明,不是品質判斷——很多好用的 library 都把長篇說明放在 code 外面;但如果你的工作流程是「直接讀 source 來理解方法」,那這一塊大多只會告訴你名字,不會告訴你行為。
授權:MIT,一路延伸到底層 driver
meta-package 與 botasaurus-driver 都宣告使用 MIT,並帶有標準的 License :: OSI Approved :: MIT License classifier。MIT 是寬鬆授權:沒有 copyleft 義務,不要求你開放自己的程式碼,商業導入也很少阻力。這和相鄰的 anti-detect driver nodriver 形成了真正而且不小的對比——nodriver 使用的是 AGPL-3.0,這種 copyleft 授權還帶有網路使用條款,會讓很多法務單位很緊張。如果授權是你的決策門檻,Botasaurus 的 MIT 確實是一個很實際的加分項。
不過還是要回到 meta-package 這件事。這個寬鬆的 MIT,涵蓋的是 Omkar Cloud 自家發佈的第一方 wheel;它不會自動代表那大約 40 個轉依賴的授權都一樣,每個依賴都有自己的 license。我確認了 Omkar Cloud 發佈的套件本身是 MIT,但沒有逐一審查整個依賴樹的每個 license。對業餘專案來說,這種差異通常不重要;但如果你要把整棵樹導入到一間重視 SBOM 的公司裡,那 40 個套件的依賴樹,最好在正式採用前先跑一次你自己的 license scanner——不是因為我發現了問題,而是因為我沒有逐一檢查,而 meta-package 正是最容易藏住意外授權的地方。
優點與缺點
優點:
- 三層裝飾器設計乾淨(
@browser/@request/@task),而且三個入口都確認存在——框架真的把常見情境寫短了。 - meta-package 與 driver 都是 MIT 授權,和同類 anti-detect driver 的 AGPL-3.0 形成明顯對比。寬鬆、適合商用、沒有 copyleft。
- driver 的 API 面很廣:99 個公開方法、18 個參數的 constructor,涵蓋一般 browser automation 需求。
- 我在 Python 3.14.2 與 3.12.13 上都完成安裝並通過 import smoke test,版本比它的 classifier 宣稱還新;但未證實完整執行相容性。
- 在我量到的 stack 裡,預設讀取對 late-injected 內容的容忍窗口最寬:load 後 300 ms 才注入的內容仍能抓到,而 nodriver、Playwright 與 Puppeteer 都在 100 ms 時就漏掉了。
wait_for_complete_page_load=True確實有在做事。 - 預設狀態下
navigator.webdriver會是false,而兩個原生控制組都是true,而且不是靠 patch property;descriptor 仍是 browser 原生 getter。 - 設計上就是「全配套」——快取、平行執行、driver 重用,以及 JSON/CSV/Excel/HTML 輸出都內建,不需要額外拼裝。
缺點:
- 磁碟占用重:122.3 MB、44 個套件,約是專注型 driver 的 7 倍,主要來自 numpy(30.9 MB)與 lxml(19.2 MB)等依賴,而不是那個約 4 MB 的 driver 本體。
- 看起來很快的 0.08 ms 頂層 import 其實誤導人;你真正會依賴的 engine import 大約要 135 ms,匯入後 resident memory 也有約 29–30 MB,而且瀏覽器還沒啟動。
- 那個較寬鬆的預設讀取窗口不是免費的:同一頁面、同一個 Chrome,每次 navigate-and-read 大約要 401–431 ms,而輕量 driver 只有 119–129 ms。
- headless 模式預設還是會在 user-agent 裡寫
HeadlessChrome,跟原生控制組完全一樣;雖然 constructor 有user_agent參數,但預設不會幫你設好。 - 以 122 MB 來說,它仍然不附帶瀏覽器——它只是驅動主機上已經存在的 Chrome,所以對外顯示的 browser 版本,就是你機器上裝的版本。
- 這次測試中,第一次使用
@request觸發了一次約 12.8 MB 的下載;由於 artifact 和目的地沒有被充分記錄,我不把它當成穩定的 footprint 增量。 - 頂層套件幾乎是空的,也沒有
__version__;真正的 API 和版本資訊都藏在沒那麼直覺的位置。 - 多數帶有 anti-detection 命名的方法在程式碼裡都沒有 docstring,所以讀 source 只能知道名字,不能直接知道行為。
不在這些數字涵蓋範圍內,因此本次未測的項目,包括:真實世界 anti-bot 效果、每頁記憶體、proxy 與 profile 處理、大規模吞吐量,以及 macOS arm64 以外的任何平台。這次量到的 footprint 與 import 數據,都是在沒有啟動瀏覽器的情況下產生的;而內容抓取與揭露相關的數據,則只來自瀏覽器與我在 127.0.0.1 上提供的 fixture 互動。
它適合誰,不適合誰
如果你想要的是一個 framework,而不是一個零件,Botasaurus 很適合。假如你是從空白檔案開始做爬蟲,寧可直接採用一套結構,而不是自己拼:入口用裝飾器、快取與平行執行都處理好、輸出寫入器內建,那這是一個合理、而且 MIT 授權的選項。MIT 很寬鬆,但你的使用與散佈模式,仍然值得照一般流程做合規檢查。已經習慣 Scrapy 或 Crawlee 思維的團隊,會對它的框架方式很有共鳴。
如果你的部署環境對體積很敏感,那就先別急著上,至少要多想一下。122 MB 的安裝量,還帶著 numpy 和 gevent,當你的實際需求只是「驅動瀏覽器並抓幾個欄位」時,這塞進精簡 container 裡確實偏大。專注型 driver 能以極小的重量完成自動化,只是你得自己把周邊 plumbing 補起來。如果你要的是 anti-detection 效果的判斷,那就乾脆跳過,因為那正是我刻意沒有測的地方——你會是在相信一個我既沒有證實也沒有否定的行銷說法。
替代方案,以及 Thunderbit 在哪裡
先講清楚現實:Botasaurus 是免費、MIT 授權、可自架的。你自己管機器、自己處理更新、自己承擔整條依賴樹——整整 44 個套件——包括 patch、license 合規,以及 numpy 未來版本可能帶來的一切。對很多團隊來說,這種 ownership 正是他們要的;沒有任何 managed service 能在純成本上贏過「你本來就有的 framework」。
如果從 open source 來比,最有意義的是看形狀。當你站在 Botasaurus 這種 framework 端時,Scrapy 與 Crawlee 就是最直接可比的對手——成熟、意見鮮明,而且各自都有自己的使用慣例。若你要的是從頁面產出適合 LLM 的 Markdown,而不是一個完整 crawler 框架,那 Crawl4AI 與偏內容抽取的 Trafilatura 就是專門做這件事的。如果你喜歡 Python 與 anti-detect 這個方向,但又想要比 meta-package 更輕一點,Scrapling 值得一看;如果你能接受編譯語言,那 Go 的 Colly 會用速度與極小體積,換掉 JavaScript rendering。任何 browser-driving 方案,包括 Botasaurus,在 Playwright 與 Puppeteer 比較 中都會繼承同樣的成本輪廓——真實瀏覽器本來就不便宜,這也是為什麼圍繞它們的框架會有這樣的重量。
如果進到 managed API,那就是同一條 pipeline 裡的另一個節點。Botasaurus 是自架的開發者工具棧;Thunderbit 則是對同一群開發者提供的 managed 版本。Open API 只有兩個 endpoint。POST /distill(1 credit)會把頁面轉成乾淨、可直接給 LLM 使用的 Markdown,渲染與 anti-bot 都在伺服端處理,所以你根本不用 provision 瀏覽器,也不用帶一整棵依賴樹。POST /extract(20 credits)則會依你定義的 JSON Schema 回傳結構化 JSON,並可依頁面實際需求把 renderMode 設成 none、basic 或 full。兩者都支援 batch 版本,一次最多 100 個 URL。還有給 agent 與 coding assistant 用的 MCP server——thunderbit_suggest_fields 是免費的,可以先告訴你頁面暴露了哪些欄位,讓你在花費前先知道能抓什麼——以及可透過 npx @thunderbit/thunderbit-cli 使用的 CLI,適合 cron 與 CI。若你不是開發者、不想碰這些,Chrome extension 可以把同一套引擎當成 no-code 工具來用,而 Thunderbit 的 YouTube 頻道 也有常見工作流程教學。
真正的取捨不是「哪個工具比較好」,而是工作放在哪裡。Botasaurus 把 framework、瀏覽器 fleet、依賴、基礎設施與維護都留在你這邊,且不用每次 request 付 vendor fee;但 compute、頻寬、proxy 與維運還是要花錢。Managed API 則是把 rendering 與 schema 化輸出從你的工作表上拿掉,改按 call 計費——你可以到 pricing page 直接拿它跟自架方案比。
結論
如果你想要一個 all-in-one 的 Python framework,而且能接受它的依賴體積,Botasaurus 算是合理的候選。三裝飾器設計很乾淨,driver 介面也夠廣,而且在我機器上,它連安裝與 import 的 smoke test 都能通過,版本還比它的 classifier 宣稱得更新。以我本地的 fixture 來看,它的預設快照也能抓到 load 後 300 ms 才注入的內容,而其他測試 stack 在 100 ms 就會漏掉;但那是 fixture 的結果,不是通用排名。
不過數字要看準。這是一個 122 MB、44 套件的安裝,driver 只有約 4 MB,剩下的是 numpy、lxml、gevent 等一堆東西——大約是專注型 driver 的 7 倍,這些重量會直接反映在你的 container image 與 cold-deploy 時間上。那個看起來很漂亮的 0.08 ms 頂層 import,只是一個空門面,不代表框架輕;真正要付帳的是約 135 ms 的 engine import。那個比較寬鬆的預設讀取,每次 navigation 也要多花約 250 ms。而在我能實際回答的預設揭露資訊問題上,情況其實比行銷說法窄:只有一個 boolean 跟原生 Puppeteer 不同,headless 的 user-agent 仍然寫著 HeadlessChrome,其他量到的屬性則在四個 stack 間完全一致。這個工具最會賣的 anti-detection 說法,正是這篇評測刻意不打分的部分——我確認了那些方法存在,也用 driver 跑了我自己機器上的頁面,然後就停在那裡,這是刻意為之。只要你看清 footprint、別被漂亮的 import 數字騙了,並把 stealth 行銷當成一個尚未回答的問題,Botasaurus 就是一個很像 framework 該有樣子的工具。若你期待的是 featherweight driver,docker build 的時間就會讓你意外。


