19 個網域,四種類別

樣本分四類,每一類的正確答案都能獨立覆核:十個仍在有效備案狀態的冷門網域(備案號與主體名稱可在工信部系統比對)、一個曾經備案但已失效的網域、五個中國大型網站(baidu、taobao、qq、zhihu、bilibili,備案號公開可查),以及三個確定沒有備案的網域(google.com、github.com,還有我們自己的 kineticlinks.net)。

最後那三個是反向對照,用途是抓「亂猜」——工具如果把它們判成有備案,那它回報的就不是查詢結果。對照組則選了一個公開的免費 ICP 查詢 API,使用它文件上的展示金鑰呼叫。兩邊跑的是同一批網域。

測試類別 Kineticlinks 對照組(免費公開 API)
冷門網域,皆有有效備案(10 個) 10 / 10 1 個正確;8 個回報「查詢失敗或沒有備案」;1 個回報成功但欄位內容是「查詢失敗」
曾備案、現已失效(1 個) 1 / 1 1 個正確
中國大型網站(5 個) 5 / 5 5 個全部正確,備案號與主體名稱皆相符
確定沒有備案(3 個,反向對照) 3 / 3 1 個正確;1 個回報可重試的錯誤;1 個誤判為有備案
同一批 19 個網域的結果。最後一列是多數人不會測、卻最能看出問題的一類。

值得先看的是最後一列。大多數人測查詢工具時只會丟有備案的網域進去,但真正暴露問題的往往是反向對照——正確答案是「沒有」的那一種。

三個發現

同一批資料裡,有三件事值得分開講。

  1. 失敗集中在唯一有鑑別力的那一類 對照組在五個中國大型網站上全部正確,備案號與主體名稱都對;但在十個冷門備案網域上只答對一個。這個分布不是隨機的,它指向資料覆蓋率——熱門網域被收錄、被維護,冷門網域可能從來沒進過那份資料。而冷門網域正是實際會拿去查的對象。
  2. 回報「成功」,但每個欄位都是「查詢失敗」 有些查詢回傳的 HTTP 狀態是 200、code 欄位也是 200,但 icp、unit、domain、time 每一個欄位的值都是字串「查询失败」。對串接的程式來說這是一次成功的查詢,那四個字會被當成備案號與主體名稱寫進資料庫。這比直接回報錯誤難發現得多。
  3. 同一個網域,不同時間得到不同答案 我們跑了兩輪。第一輪 kineticlinks.net 拿到上述那種「成功但內容是查詢失敗」的回應;第二輪它回報正確,換成 google.com 和 0592tk.com 拿到同樣的壞回應。也就是說這個行為是間歇性的——測一次通過,不代表下一次也通過。

為什麼「成功」比「失敗」更危險

把 google.com 丟進對照組,拿回來的是這樣的內容——HTTP 200,code 200,一次語法上完全成功的查詢:{"code": 200, "icp": "查询失败", "unit": "查询失败", "domain": "查询失败", "time": "查询失败"}

google.com 當然沒有 ICP 備案。但這個回應沒有任何一處指出查詢失敗了:狀態碼是成功的,備案號欄位有值。串接的程式如果寫成 if resp["icp"]: mark_as_filed()——這是最自然的寫法——它就會把 google.com 標記為已備案,並把「查詢失敗」四個字當成備案號存進去。

同樣形狀的回應也出現在 0592tk.com 上——那是一個確實有備案的網域。所以這個欄位的值既不能證明有備案,也不能證明沒有,它單純是把錯誤訊息塞進了資料欄位。從外部看,兩種完全相反的情況長得一模一樣。這不是準確率高低的問題,是回應設計的問題:錯誤沒有自己的表達方式。任何查詢類 API 都該讓「確定有」「確定沒有」「這次查不到」三者在結構上可區分,否則接的人無從判斷。

這組測試不能證明什麼

樣本是 19 個網域、一個對照組、單一時間點(2026 年 9 月 29 日)。這不足以推論任何工具的整體準確率,也不該被當成通則——它是這組測試裡發生的事,不是產業結論。幾個限制要講清楚:冷門網域樣本全部來自同一批來源,不是隨機抽樣;對照組用的是公開展示金鑰的免費端點,付費方案的資料來源與品質可能完全不同。我們也刻意沒有比較速度——該免費金鑰約每 20 秒才允許一次查詢,我們為了配合它而放慢呼叫,把那個耗時拿來當效能比較會是不誠實的。

還有一點必須直接講:受測的其中一個工具是我們自己的,測試也是我們自己設計與執行的。我們自己的工具同樣有過這類問題——在更早的測試裡它對中國大型網站一律回傳 unknown,也曾因為速率限制而大量失敗,兩者都是在這次測試過程中才發現並修掉的。第一輪比較還因為我們呼叫得太密集,把對照組打到限流,那一輪的結果是我們自己的問題,已作廢重跑。把這些寫出來,是因為一篇只呈現自己全對的比較文沒有參考價值。真正值得帶走的是方法,不是分數。

自己驗證一個查詢工具的三個步驟

不論最後選哪一個,這三步能在接進系統前先篩掉不能用的:

一、樣本裡一定要有冷門網域與反向對照

只用知名網站測等於沒測。找幾個您已經知道答案、但沒什麼名氣的網域,再加上兩三個確定沒有備案的網域。後者是抓亂猜用的——很多問題只有在正確答案是否定的時候才會現形。

二、確認「查詢失敗」和「查無備案」分得開

這兩件事意義完全相反,但不少 API 把它們壓成同一種回應。刻意送一個不存在的網域、格式錯誤的字串,或在限流狀態下呼叫,看回應長什麼樣子。如果錯誤訊息會出現在資料欄位裡,那這個 API 不能直接接進會寫入資料庫的流程。

三、同一批網域跑兩次

間歇性的壞回應跑一次看不出來。隔一段時間用同一批網域再跑一次,比對兩次的結果是否一致。不一致的地方就是您上線後會遇到、但很難重現的問題。

採購備案查詢 API 前該問的三件事

如果您要把備案查詢接進自己的系統,這三項會決定它能不能信:

  1. 資料是即時查詢還是快照 直接問,並要求說明快照的更新頻率與覆蓋範圍。這一項決定冷門網域查不查得到,也決定備案失效之後要多久才會反映出來。
  2. 失敗與「無備案」在回應上如何區分 要看實際的回應結構,不是文件上的文字描述。確認錯誤有獨立的狀態碼或欄位,而不是被塞進備案號欄位裡。
  3. 速率限制、配額與逾時行為 每秒與每日上限各是多少、超過會回什麼、上游逾時的時候是回錯誤還是回「無備案」。最後這一項最容易在上線之後才踩到。

小結

這組測試裡最值得記住的不是分數,是一種失敗的形狀:回報成功、欄位有值、值是錯的。它不會讓程式報錯,所以不會有人發現;它會安靜地把「查詢失敗」四個字寫成某個網域的備案號。查得到百度證明不了什麼,拿確定沒有備案的網域去測,反而更容易看出一個工具能不能用。

備案狀態本身也不是查一次就固定的——接入商取消接入、專項核查註銷,都可能讓它在毫無徵兆的情況下消失。如果您正在評估備案網域,或要把備案查詢接進自己的流程,歡迎把實際情況告訴我們一起看。

參考資料