2025 年最佳網頁爬蟲工具與軟體 | Thunderbit

最後更新於 August 19, 2026
2025 年最佳網頁爬蟲工具與軟體 | Thunderbit
AI 摘要
每個 Chrome 擴充功能都會附上一份 manifest.json,裡面宣告了相當大一部分的瀏覽器能力上限:要求的 API、主機匹配模式、靜態內容指令碼、可選權限,以及允許的外部連線。這是你安裝的套件裡公開可見的檔案。它無法證明執行階段程式實際用了哪些已宣告能力、哪些資料離開了你的電腦,或哪些帳號存取是透過獨立的網頁登入完成的。我檢視了這次稽核中挑選的十款網頁爬取與瀏覽器自動化擴充功能,包括 Thunderbit——也就是我們自己的產品。差異非常大。

每個 Chrome 擴充功能都會附帶一個 manifest.json,其中揭示了它在瀏覽器層級所能觸及的能力邊界:要求哪些 API、可匹配哪些網站模式、是否載入靜態內容腳本、可選權限有哪些,以及允許哪些外部連線。這份檔案公開存在於你安裝的套件中。它不能證明執行時程式實際用了哪些已宣告的能力、資料是否離開本機,或是否有透過另一個網站登入來存取帳號。

我讀取了這次審核所選的十個網頁爬蟲與瀏覽器自動化擴充功能的 manifest,包括 Thunderbit 的版本,因為那是我們自己的產品。這些擴充功能的差異非常大。有一個完全沒有宣告常駐站點存取;另一個則宣告了 13 項權限,還包含 clipboardRead。Thunderbit 是這組裡唯一宣告 debugger 的擴充功能,這代表它可附加 CDP,風險輪廓和頁面存取、OAuth 或使用者自行提供的腳本都不一樣。

這些都不是指控。廣泛的權限宣告,很多時候只是為了實現某個功能所必須付出的誠實代價;而權限較少,也可能只是代表產品本來就做得比較少。重點是:這種差異非常大,而且是公開可查的,但它從來不會被放進比較表裡。

這項分析怎麼做的

每個擴充功能都是從 Google 自家的更新端點下載成 .crx 檔——也就是 Chrome 本身使用的同一個 URL——接著解包並解析。**沒有安裝任何擴充功能,也沒有執行任何擴充功能程式碼。**這只是對一個 JSON 檔案的閱讀。

下載節奏大約是每兩秒一筆。每個 .crx、其 SHA-256,以及解出的 manifest.json 都被保留為證據。Thunderbit 也和另外九個擴充功能一樣走同一套腳本,不是走特別通道,所以它的那一列和其他產品是用完全相同的方法得出的。

這份分析使用兩類證據,並將兩者分開處理:

  • 已宣告的靜態行為: host pattern 與 content_scripts 項目,包括 matchesrun_atall_frames
  • 執行時程式可用的能力: permissionsoptional_permissions 裡列出的 API。這些宣告只代表程式可能請求或呼叫哪些能力,不代表它真的有這麼做。

這裡沒有指定任何「最強」的排序。debuggeruserScripts、廣泛的 host 存取、OAuth scope、剪貼簿存取,以及外部訊息傳遞,暴露的是不同類型的資料,也需要不同的前置條件。要比較它們,必須先有一套威脅模型,而這種只看 manifest 的審核並沒有提供。

下方數字都是解包後的總大小,以 MiB(2²⁰ bytes)計算,並依 ZIP entry 加總。

截至 2026-07-29。 擴充功能會更新;引用前請重新檢查。

十個 manifest 各自宣告了什麼

Measured results chart: Declared permission strings

官方參考資料:Chrome 權限宣告指南

擴充功能版本解包後大小檔案數權限數網站存取範圍可觸及 file://
Axiom.ai5.1.037.1 MiB2328http://*/* + https://*/*
Table Capture11.0.4121.1 MiB1154 (+3 個可選)<all_urls>
Magical3.119.116.8 MiB39513(+2 個可選)<all_urls>
Thunderbit(我們的)4.6.415.9 MiB788 個已識別(+1 個未識別的陣列字串:commands<all_urls>
Clay for Chrome1.0.06.3 MiB516*://*/*(僅在自家網域注入)
Listly0.9.63.5 MiB847http://*/*https://*/*file:///*.html
Hexomatic1.8.42.7 MiB372僅自家網域
Agenty2.9.72.2 MiB494未宣告
Clip to Clay1.8.00.7 MiB1642 個指定網域
TexAu v21.6.60.3 MiB12614 個指定網域

另外還有兩個原本在候選清單中,但因為各自值得單獨說明,所以沒有放進表格。

差異是設計選擇,不是大小造成的

**Agenty 沒有宣告任何 host 權限,也完全沒有內容腳本。**它的四個權限是 activeTabscriptingidentityidentity.emailactiveTab 是比較窄的那一種:它只在你點擊擴充功能後,才授予目前分頁的存取權,而且只持續到你離開該頁面為止。若你不主動呼叫,頁面上什麼都不會執行。它的大小是 2.2 MiB。

Axiom.ai 則宣告了 http://*/*https://*/*,並以 <all_urls> 匹配注入內容腳本,解包後 37.1 MiB、共 232 個檔案——是 Agenty 的 17 倍,而且對你造訪的每一個頁面都有常駐存取權。

Hexomatic 和 Agenty 比較接近:只有兩個權限(storagetabs),沒有 host 權限,內容腳本也只限制在它自己的兩個網域。

Clay for Chrome 則是第三種型態,值得另外區分:它把 *://*/* 當作 host 權限,但內容腳本只注入自家網域。它的常駐能力很廣,但自動化行為很窄。只看權限表,這兩件事會被混在一起。

十個裡面有五個能碰到你電腦上的檔案

file:/// 不是網站。它是把你的本機檔案系統以瀏覽器分頁形式呈現出來的內容——你打開的 PDF、HTML 匯出檔、下載的發票都算。

官方參考資料:Chrome match pattern 文件

其中三個擴充功能明確寫了這件事。另兩個則是沒有明寫,但一樣能到達:<all_urls> 本來就包含 file: scheme。

擴充功能它如何觸及 file://manifest 裡是否明寫 file://位置
Magical在六個內容腳本項目中的四個,匹配 file:///*——Chrome 會渲染的所有本機檔案,不只 HTML內容腳本,以及 web_accessible_resources
Listly匹配 file:///*.html內容腳本
Table Capture透過 <all_urls> 內容腳本,且它也有明寫這個 schemeweb_accessible_resources
Axiom.ai純粹因為用了 <all_urls> 萬用字元沒有明寫
Thunderbit(我們的)純粹因為用了 <all_urls> 萬用字元沒有明寫

http://*/*https://*/* 不涵蓋 file://<all_urls>*://*/* 在這點上也不同。這裡列出的五個,是因為它們的宣告透過某種路徑碰到了這個 scheme——不是因為它們用了哪種萬用字元就必然如此。

Chrome 會把這件事放在每個擴充功能各自的「Allow access to file URLs」開關底下,而且預設是關閉的,所以這份宣告只是請求,不是直接授權。五個中的五個是誠實的計數,而其中兩個甚至從頭到尾都沒在 manifest 裡寫過 file://:Axiom.ai 和我們自己的 Thunderbit。

這個計數包含 web_accessible_resources,不只是內容腳本與 host 權限。Table Capture 在那裡明寫了 file://*/*;如果漏看這一段,就會錯把它歸到那些沒有明寫 scheme、但 manifest 仍可觸及本機檔案的擴充功能裡。

你看不到、但它們可在執行時才要求的權限

System diagram: Permissions you can't see until they're requested

optional_permissions 會先在 manifest 中宣告,但要到執行時才請求,因此不會出現在安裝時的權限提示裡。這次有兩個擴充功能使用了它,而其中一個相當重要。

擴充功能optional_permissions真正重要的是哪一個
Table CaptureuserScriptsdownloadsidentity啟用 Chrome 的使用者門檻後,userScripts 可在頁面情境中執行使用者提供的腳本
MagicaldownloadswebRequestwebRequest 會觀察網路流量

userScripts 在被請求之前是不存在的,而且對任何只會看權限數字的人來說,它是看不見的。

它還有一個這次審核中其他權限沒有的門檻,如果不把這點說明清楚,就會高估它的能力。要使用 userScripts,不只是宣告就夠了:Chrome 會先要求明確的使用者動作。 在 Chrome 138 之前,這個門檻是全域開關的 Developer Mode,要在 chrome://extensions 中開啟。從 Chrome 138 起,變成該擴充功能詳細頁上的「Allow User Scripts」獨立切換,且預設關閉。所以對一般安裝而言,這項能力是被宣告了,但實際上沒有啟用。最精確的說法是:使用者先打開 Chrome 的門檻後,Table Capture 才能讓 userScripts API 可用。本次審核沒有量測有多少使用者會去打開那個設定或切換開關。

這兩者都不是隱藏起來的;都寫在 manifest 裡。若忽略 optional 區塊,會低估這兩個產品。

不只看範圍,也要看注入時間

內容腳本怎麼注入,常常被忽略,但它會改變整體圖景。document_start 是 Chrome 提供的最早掛鉤;all_frames 會涵蓋第三方嵌入框架。

以下是這組裡所有靜態注入到所有 frame 的項目,依宣告時間排序:

擴充功能run_atall_frames內容腳本匹配模式
Table Capturedocument_start<all_urls>
Listlydocument_startfile:///*.html 加上所有 http 與 https
Axiom.aidocument_start僅自家網域
Clay for Chromedocument_start僅自家網域
Thunderbit(我們的)document_end<all_urls>
Magicaldocument_idlefile:///* 加上廣泛的 http 與 https
TexAudocument_idle(未設定)十四個指定模式

Table Capture 與 Listly 都是在廣泛匹配模式下,用最早的掛鉤時機注入。Axiom.ai 和 Clay for Chrome 也是同樣的時間點,但只在它們自己的網域上使用—— aggressiveness 一樣,目標範圍較窄。

對靜態宣告來說,<all_urls> 加上 all_frames 就是匹配廣度的上限,而 Table Capture 與 Thunderbit 都在這個上限上。兩者的宣告時間不同:Table Capture 用的是 document_start;Thunderbit 的靜態內容腳本則是 document_end。執行時 API 是另一個能力類別,不能從這張表直接推論。

只看權限數是很差的摘要統計。 Table Capture 只宣告四個權限——比這裡大多數都少——但它卻在 <all_urls> 上,以 document_start、對所有 frames 注入,並在需要時還能用 userScripts

誰可以向這個擴充功能送訊息

externally_connectable 控制哪些網頁或其他擴充功能,可以直接向擴充功能的背景腳本送訊息。它的預設值很反直覺。

如果把這個鍵整個省略,反而是較寬鬆的設定。 Chrome 的預設行為是:當 externally_connectable 不存在時,任何擴充功能都可以連線,但任何網頁都不行。 如果你有明寫這個鍵,才是在限制它。

照這個規則來看,表格就會翻轉:

擴充功能externally_connectable 宣告誰可以向它送訊息
Agenty省略寬鬆預設——任何擴充功能都可連線,任何網頁都不行
Clay for Chrome省略寬鬆預設——任何擴充功能都可連線,任何網頁都不行
Clip to Clay省略寬鬆預設——任何擴充功能都可連線,任何網頁都不行
Listly省略寬鬆預設——任何擴充功能都可連線,任何網頁都不行
Table Capture省略寬鬆預設——任何擴充功能都可連線,任何網頁都不行
TexAu省略寬鬆預設——任何擴充功能都可連線,任何網頁都不行
Thunderbit(我們的)省略寬鬆預設——任何擴充功能都可連線,任何網頁都不行
Hexomatic八個擴充功能 ID 六個 web origin從封閉基線打開兩條通道
Axiom.ai七個 web origin,沒有 ids擴充功能通道關閉,開放了七個網頁
Magical{"ids": [], "matches": []}這裡唯一同時明確關閉兩條通道的擴充功能

Chrome 的規則有兩層。以下摘自 manifest 參考文件:

情況誰可以連線
整個鍵 不存在「所有擴充功能都可以連線,但沒有網頁可以連線」
鍵存在,ids 未設定或為 []「沒有任何擴充功能或應用程式可以連線」
鍵存在,matches 未設定或為 []「沒有任何網頁可以連線」

所謂寬鬆預設,取決於整個鍵都不存在。一旦這個鍵存在,兩個子欄位都會先預設關閉,只有在指定值後才會把各自通道打開。

Axiom.ai 只宣告了 matches,沒有宣告 ids 這代表它的 ids 是未設定狀態,也就是說沒有任何擴充功能能對它送訊息——擴充功能通道是關閉的,不是打開的。它真正打開的是七個 web origin,其中只有一個是 Axiom 自家網域:兩個是無法直接歸屬的第三方 (*://*.tgwc.space/**://*.bitmachine.co.uk/*),其餘則是 localhost0.0.0.0、一個 Google APIs 主機,以及一個它並不營運的大型社群平台。

Hexomatic 把擴充功能通道開給八個指定 ID。 在鍵存在的前提下,基線是零個擴充功能;指定八個之後就變成八個。它的六個 matches 也把另一條通道從無擴大到有,而其中兩個是透過明文 HTTP 的 http://localhost:8000/*http://localhost:3000/*——只要使用者機器上有任何服務在這些連接埠回應,都會被納入 allowlist。

十個裡有七個完全省略這個鍵,包括我們自己的 Thunderbit,而這七個都落在擴充功能對擴充功能訊息傳遞的寬鬆預設上。另有兩個擴充功能把這條通道關掉:Magical 用 ids: [] 明確關閉;Axiom.ai 則是宣告了這個鍵,但從未提到 ids。Magical 是唯一一個把兩條通道都關掉的。

最後這一點,就是為什麼要讀 manifest,而不是只數權限。同一個擴充功能,可能在某個面向非常寬,在另一個面向卻是這組裡最嚴格的。

沒人會統計的那個軸:OAuth scopes

manifest 可以包含 oauth2 區塊,而裡面的 scopes 代表你對其他公司的帳號授權——這和前面那些能力是不同層次的存取範圍,而且沒有任何權限數字能反映出來。

官方參考資料:Google OAuth 2.0 scope 清單

擴充功能要求的 oauth2 scopes
Axiom.aiopenidemailprofileauth/driveauth/spreadsheets
Table Captureauth/spreadsheetsauth/userinfo.email
Agentyopenidemailprofile
其餘七個,包括我們的未宣告

https://www.googleapis.com/auth/drive 是比較廣的那一種。Google 另外提供較窄的 drive.file scope,只能存取應用程式自己建立的檔案,或使用者明確選取的檔案;而 auth/drive 則能查看、編輯、建立與刪除使用者整個 Drive 裡的內容。auth/spreadsheets 對帳號可接觸到的每一份試算表也同樣如此。Axiom.ai 與 Table Capture 都把 Google 帳號 scope 和 <all_urls> 的頁面存取一起用。

這張表只能證明兩件事。第一,scope 是被請求,不是被授予——Google 會顯示同意畫面,使用者可以拒絕,而擴充功能也可能根本不會呼叫那個 API。第二,manifest 只看得到透過 Chrome identity 流程完成的 OAuth;如果某個擴充功能是把你導到網站登入頁,它在這裡就不會寫任何東西。那七個零只代表「這個檔案裡沒有請求」,不是「沒有存取你的 Google 帳號」——包括我們自己的 Thunderbit 也是,所以這個軸是報告出來,而不是拿來主張它很窄。

我們自己的擴充功能,放在同一把尺上看

Thunderbit 4.6.4 也走了和另外九個相同的 manifest 解析器。這個套件解包後是 15.9 MiB,共 78 個檔案。

已宣告的靜態行為: host_permissions 與內容腳本匹配裡都出現了 <all_urls>。靜態腳本會在 all_framesdocument_end 執行。由於 <all_urls> 包含 file:,在使用者打開 Chrome 的檔案存取開關後,manifest 就能觸及本機檔案。Thunderbit 也省略了 externally_connectable,所以 Chrome 的預設允許任何擴充功能送訊息,但不允許任何網頁。

執行時能力上限: permissions 陣列中有九個字串:activeTabcommandsdebuggeroffscreenscriptingsidePanelstoragetabGroupstabs。Chrome 會把其中八個識別為權限;commands 是頂層 manifest key,放進這個陣列裡不會產生效果。Thunderbit 是這組裡唯一宣告 debugger 的擴充功能,它可以把 CDP 附加到分頁上。manifest 也讓 scripting 可供執行時註冊使用。這些 API 所形成的能力,超出了靜態 document_end 那一列所能表達的範圍;但只讀 manifest 不能證明 Thunderbit 有呼叫特定 CDP method,也不能證明它有在更早的某個時間點註冊腳本。

這個區分也阻止了幾個很誘人、但其實無效的比較。沒有更窄的 cookies 權限,並不能限制有 debugger 的程式可能讀到什麼。沒有 clipboardRead,也不代表一定無法接觸剪貼簿。反過來說,宣告了 debugger 也不等於真的有用到那些路徑。要回答這些問題,得看原始碼或做執行時追蹤;這兩件事這次都沒做。

在這項工具上,Thunderbit 對靜態站點存取很寬,在這組裡又是唯一宣告 debugger 的,而且對擴充功能之間的訊息傳遞維持 Chrome 的預設。沒有任何單一的「最強」排名,因為這份審核沒有提供能同時涵蓋 CDP、OAuth、userScripts、剪貼簿與 host 存取的共同威脅模型。

這種不被行銷的克制設計

TexAu 只有 0.3 MiB——是這裡最小的,約只有第二小的一半——而且它不是用萬用字元,而是明確列出 14 個特定站點:社群網路、開發者平台、內容發布平台、聊天產品、商業資料供應商,以及它自己的網域。它的內容腳本也精準匹配同樣的 14 個目標。

你可以直接讀這份 manifest,知道這個擴充功能會在哪些地方運作。這同時也是一種產品揭露——它列出的目標,比行銷文案更直白地說明了這個工具是拿來做什麼的。

代價也是真實的:名單式設計無法抓取不在清單上的網站,每增加一個目標都要發版。但「14 個指定網域」和「任何存在的 URL」是完全不同的概念,而只有前者是可讀的。

兩個產品,原本的清單說得不對

Captain Data 的擴充功能沒有公開散佈。 Google 的更新端點對它的擴充功能 ID 回傳的是 HTTP 204 且空白內容——這通常代表商店不會匿名提供這個東西。相對地,它的 listing 頁面卻可以匿名取得:HTTP 200、509,829 bytes。抓取結果無法從中找到版本字串、最後更新日期或安裝數;腳本自己的註記也說,那裡為 null 只能算弱證據,而且沒有觀察到登入牆。這個 ID 是真實且第一方的,所以最可能的解讀是只限連結存取或未列出散佈;但我無法區分這和下架之間的差別,也不會瞎猜。

Dataflow Kit 根本沒有 Chrome 擴充功能。 它的網站描述的是一個有點選式選取與 REST API 的託管網頁應用。它原本卻還是被放進 Chrome 擴充功能的候選清單裡——這通常就是這類清單會怎麼做出來的。

就算只是免費可以查的資訊,也要看新鮮度與覆蓋範圍

商店的中繼資料,除了權限之外,也提供產品選擇脈絡。相同欄位在 2026-07-30 為每個擴充功能都被擷取了一次。

擴充功能商店版本最後更新安裝量級
Thunderbit(我們的)4.6.42026 年 7 月 28 日200,000
Listly0.9.62026 年 7 月 25 日100,000
Axiom.ai5.1.02026 年 7 月 20 日100,000
Table Capture11.0.412026 年 6 月 26 日200,000
Magical3.119.12026 年 4 月 4 日200,000
Agenty2.9.72026 年 2 月 8 日10,000
TexAu1.6.62025 年 8 月 20 日7,000
Clay for Chrome1.0.02025 年 4 月 9 日10,000
Clip to Clay1.8.02025 年 4 月 8 日1,000
Hexomatic1.8.42024 年 9 月 6 日3,000
Captain Data未公開提供

有三個產品已經超過一年沒有發版,Hexomatic 則接近兩年。對擴充功能來說,這比對程式庫還重要:Chrome 大約每四週就會推出穩定版,而擴充功能平台本身也會持續變動。userScripts 在 Chrome 138 改了使用者門檻;一個最後一次發版停留在 2024 年的擴充功能,是在不同規則下寫成的,而現在的瀏覽器卻是在強制執行另一套規則。

這張表有兩件事不是。第一,安裝數是 Google 分級後的區間值——1,000 / 3,000 / 7,000 / 10,000 / 100,000 / 200,000——所以它只能比較數量級,不能更細,而有些產品在自己的行銷裡還會寫更大的數字。第二,更新日期只是發版事實,並不能直接判定維護品質或權限風險。

有一個很有用的副產品:在這次分析的十個套件裡,商店版本都和 manifest 版本一致。 這份審核解析的是商店今天正在提供的 CRX,不是過時副本。

新鮮度會影響某個選項值得做多少後續檢查,但不會改變 manifest 語意。某個使用指定網域、且一年沒更新的擴充功能,仍可能比昨天才發版的萬用字元擴充功能更少暴露頁面範圍。如果這個新套件能更快跟上 Chrome 變動,它在實務上也可能是比較好的選擇。做 shortlist 時,先用商店日期決定哪些要重測,再用 manifest 判斷哪些需要更深入的能力審查。不要把這兩欄硬合成一個分數。

manifest 不會告訴你的事

已宣告的權限只是上限,不是行為本身。 <all_urls> 代表擴充功能可以讀取你造訪的每個頁面;它並不表示真的有這樣做,也不代表任何資料一定會離開你的裝置。要確認真實發生了什麼,必須在執行時觀察網路流量——那是不同的工作,這裡沒有做;因此,上面任何內容都不應被解讀為濫用證據。

相關審查:Chrome 擴充功能可測試性實驗

還有三個界線:

  • Chrome 本身會限制很多事情。 檔案存取預設關閉;activeTab 故意設得很窄;可選權限需要執行時提示;使用者在安裝時會看到權限清單。
  • 廣泛權限常常是必要的。 一個工作目標是「從你目前看到的任何頁面擷取表格」的工具,不可能只靠指定網域 allowlist 運作。範圍窄,有時是紀律;有時只是產品功能比較少。
  • 一個版本,只代表一天。 每一個數字都來自 2026-07-29 當天提供的套件。

分析中的重要修正

這些公開數字用了三個很容易在快速寫 manifest parser 時弄錯的規則。第一,<all_urls> 包含 file: scheme,但 Chrome 仍把真正的檔案存取放在使用者可控的開關後面。第二,web_accessible_resources.matches 必須和內容腳本與 host 權限一起看;Table Capture 就是在那裡明確寫了 file://*/*。第三,externally_connectable 的預設值,取決於整個鍵是否缺失,或是鍵存在但某個子欄位是空的。上面的表格都是一致地依照這些規則處理。

Thunderbit 的權限總數,也有把原始字串和 Chrome 可識別權限區分開來。它的陣列裡有九個項目,但 commands 屬於頂層鍵,所以這裡實際採用的是八個已識別權限,加上一個未識別字串。最後,靜態 content_scripts 宣告,並不代表程式真的呼叫了 scripting.registerContentScripts 或某個 CDP method。這些可能性只屬於執行時能力,而不是已觀察到的行為。原始 manifest、CRX 雜湊與 parser 輸出,才是這些標準化結果的審計軌跡,因此讀者不需要只靠文意來相信它。

如果真的要做安裝決策,至少要分開比較四個面向:預設哪些頁面在範圍內、哪些明確的使用者動作會解鎖更大範圍、哪些瀏覽器或帳號 API 會變得可用,以及哪些外部呼叫者能向擴充功能送訊息。Agenty 的 activeTab 模式、Table Capture 受門檻控制的 userScripts、Axiom.ai 的 Drive scope,以及 Thunderbit 的 debugger 宣告,都不是同一條線上的不同點;它們是在回答不同的威脅問題。

以下是把這四種刻意不同的設計放在一起比較:

擴充功能manifest 中可見的頁面範圍額外門檻本次審核中的非頁面能力外部呼叫者狀態
Agenty沒有 host 權限,也沒有靜態內容腳本使用者在目前分頁點擊 activeTabChrome identity 權限鍵省略:任何擴充功能都可連線,任何網頁都不行
Table Capture<all_urls> 的所有 frames 中,於 document_start 注入靜態腳本檔案存取預設關閉;userScripts 需要 Chrome 的獨立使用者門檻可選 userScriptsdownloadsidentity鍵省略:任何擴充功能都可連線,任何網頁都不行
Axiom.aiHTTP 與 HTTPS 萬用存取;在自家網域以 document_start 注入靜態腳本針對所請求的 Google scopes 進行 OAuth 同意已宣告的 Drive 與 Sheets OAuth scopes擴充功能呼叫者關閉;開放七個 web origins
Thunderbit<all_urls> host 存取,且在所有 frames 中以 document_end 注入靜態腳本檔案存取預設關閉;附加 debugger 具有 Chrome 控管的使用者可見行為已宣告 debuggerscriptingtabs 與相關瀏覽器 API鍵省略:任何擴充功能都可連線,任何網頁都不行

這張表還是無法得出誰最好。Agenty 的常駐頁面存取很窄,並不代表它後端對送出的資料做了什麼。Axiom.ai 的帳號 scopes 也不能和讀取目前頁面的擴充功能直接相比。Table Capture 的 userScripts 宣告,直到使用者啟用它自己的獨立門檻前都只是無效宣告。Thunderbit 的 debugger 權限暴露了很廣的瀏覽器控制面,但 manifest 沒有透露它實際呼叫哪些 CDP domains 或 methods。每一列真正告訴你的是下一步要看什麼:執行時網路流量、原始碼、同意流程,或瀏覽器 API trace。

System diagram: How to read your own

同樣的切分,在閱讀 Chrome 的安裝提示時也很重要。單看權限數,無法反映時機、frame 範圍、OAuth scope、web_accessible_resources,或被省略的 externally_connectable 鍵。反過來說,一個廣泛宣告也不等於真的有蒐集或外傳。manifest 審核真正有用的輸出,是一份優先排序過的執行時測試計畫:先辨識資料面,標記使用者門檻,再觀察宣告的路徑是否真的被使用。

如何讀自己的 manifest

相關審查:瀏覽器自動化指南

  1. chrome://extensionsDetails 會顯示已授權的網站存取範圍,也能把不需要常駐存取的項目切成 on click。這會縮小上面提到的站點存取那一半,但不會影響進來的訊息傳遞(externally_connectable 仍會照樣觸及 service worker),也不會影響瀏覽器層級權限。 Thunderbit 的 debugger 宣告在這裡特別重要。Chromium 自己的擴充功能安全文件說,debugger API「在某些情況下也可能繞過其他典型限制,例如 host 權限或檔案存取」,所以把 site access 設成「on click」並不能限制它可觸及的範圍。這個控制也不會影響 tabswebNavigationclipboardReaddownloads,或 optional_permissions 裡的任何項目。
  2. 原始檔位在 Chrome 的 Extensions/<id>/<version>/ 目錄下。請讀六個欄位:permissionsoptional_permissionshost_permissionscontent_scripts(其中的 matchesrun_atall_frames)、externally_connectable——記得缺失這個鍵時,對擴充功能呼叫者是寬鬆的——以及 web_accessible_resources,其中的 matches 可以指定內容腳本未曾列出的 scheme。Thunderbit 的最後一欄有兩個 <all_urls> 項目,把 index.html 與兩個打包腳本暴露給所有 origin,且 use_dynamic_url: false,這讓頁面能測試那些固定的 extension URL 是否可解析。
  3. 將 listing 的最後更新日期和目前 Chrome 版本比對。

揭露與資源:這篇文章由 Thunderbit 發布,而它自己的擴充功能也被納入同一份表格與 parser 中。我們的 開源爬蟲主題頁 涵蓋非擴充功能工具。

立即試用 Thunderbit 進行網頁資料擷取

簡短版結論

十個爬蟲與自動化擴充功能,包含我們自己的版本,都可以從各自的 manifest 讀出來。

Agenty 沒有宣告站點存取,也沒有內容腳本;你點擊它時,只會在你正在看的分頁上運作,大小是 2.2 MiB。Axiom.ai 宣告了所有 HTTP 與 HTTPS URL,整體達 37.1 MiB。Magical 宣告了 13 項權限,包括 clipboardRead——而且它也是這裡唯一完全關閉進入訊息傳遞的擴充功能。Table Capture 只宣告四個權限,但它在 <all_urls> 上、以 document_start、注入所有 frames——和我們一樣達到匹配上限,只是更早,而且還能在需要時使用 userScriptsTexAu 是最小的,也是列出目標最多的——14 個模式,分散在 13 個不同屬性上。它並不是唯一列出目標的:Clip to Clay 有兩個(clay.com 與一個第三方站點),Hexomatic 和 Clay for Chrome 也列出自己的網域。TexAu 是這些裡唯一一個主要列別人網站清單的。 十個裡有五個能觸及你電腦上的檔案,其中兩個——Axiom.ai 和我們自己的 Thunderbit——甚至從頭到尾都沒寫過 file://

Thunderbit,我們自己的版本,位在較廣的一端:host 存取與靜態注入都用 <all_urls>,再加上這組裡其他擴充功能都沒宣告的 debugger。它也維持 Chrome 的預設值,允許任何擴充功能送訊息,而且在 Chrome 的檔案存取門檻啟用後,也能觸及 file://

宣告是上限,不是行為,而這些內容也沒有顯示任何濫用。但它們是公開的、可免費檢查的,而且兩端之間的差距,比產品頁面上看起來大得多。

立即試用 Thunderbit 進行網頁資料擷取 Get Started Free

常見問題

廣泛權限是否代表擴充功能有問題?為什麼只看權限數不夠? 不代表,而且單看數量會漏掉兩件事。<all_urls> 只表示擴充功能可以讀取你造訪的每個頁面;它不說明它到底做了什麼,也不代表任何資料會離開你的裝置。真正要建立任何行為結論,得看執行時網路流量,而這次審核沒有做。另外,計數本身也不完整:注入設定不是權限,所以 Table Capture 只算四個權限,卻會在 document_startall_frames、對應 <all_urls> 注入。optional_permissions 更不會出現在安裝提示裡——Table Capture 可以在執行時請求 userScripts,而這會讓它在頁面情境中執行任意使用者腳本;Magical 則可以請求 webRequest

哪一個要求得最少? Agenty:四個權限,沒有 host 權限,也沒有內容腳本。它依賴 activeTab,只有在你點擊擴充功能之後、而且只到你離開目前分頁之前,才給予那個分頁存取權。第二少的是 Hexomatic,兩個權限,內容腳本也只限於自己的網域。

擴充功能怎麼不宣告 file:// 也能碰到我的本機檔案? 因為 <all_urls> 包含 file: scheme。Listly、Magical 與 Table Capture 都明確寫了 file:// 模式——Magical 在內容腳本中寫,Table Capture 則是在 web_accessible_resources 中寫。Axiom.ai 與 Thunderbit 則是透過萬用字元碰到它,完全沒有提到。http://*/*https://*/* 不涵蓋 file://。Chrome 把檔案存取預設關閉,放在每個擴充功能自己的切換開關後面,所以這種宣告只是請求,不是直接授權。

什麼是 externally_connectable?為什麼省略它反而比較寬鬆? 它用來指定哪些 web origins 或擴充功能 ID 可以向擴充功能的背景腳本送訊息。Chrome 的預設行為是:當這個鍵不存在時,任何擴充功能都可以連線,但沒有任何網頁可以連線。這十個裡有七個都省略了它,包括 Thunderbit。當這個鍵存在時,Hexomatic 會把擴充功能通道開給八個指定 ID;Axiom.ai 會開放七個 web origins,但擴充功能通道仍然關閉;Magical 則把兩邊都設成空清單,因此兩條通道都關掉。

Thunderbit 自己的 manifest 宣告了什麼? <all_urls> 用於 host 存取與靜態內容腳本注入,並在 document_endall_frames 中執行;15.9 MiB、78 個檔案;以及權限陣列中的九個字串。八個是 Chrome 可識別的權限:activeTabdebuggeroffscreenscriptingsidePanelstoragetabGroupstabscommands 是頂層 manifest key,放在這個陣列裡不會產生效果。這組裡沒有其他擴充功能宣告 debugger。Thunderbit 也在 Chrome 的檔案存取門檻啟用後,透過 <all_urls> 觸及 file://,並省略了 externally_connectable。本次沒有執行 runtime 行為,所以審核也沒有主張它實際呼叫了哪些 CDP 或 scripting method。

Ke
Ke
Thunderbit 技術長|資深資料科學家與機器學習專家 Ke Shen 在機器學習與資料科學領域擁有近十年經驗,畢業於哥倫比亞大學,曾任 Walmart Labs 資深資料科學家。他精通 Python、R、Java 與統計學,且具備深受同儕認可的深厚專業,分享如何將複雜的 AI 演算法從理論落實到可投入生產的架構的實戰見解。
Topics
網頁爬蟲工具AI 網頁爬蟲
目錄
Thunderbit · AI 網頁資料代理

1 次點擊 內擷取任何頁面的資料

深受 250,000+ 用戶信賴
提供免費方案
從網頁到試算表
描述你需要的內容——Thunderbit 的 AI 代理會幫你爬取,並匯出到 Excel、Google Sheets、Airtable 或 Notion。免費即可開始。
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week