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. 速率限制、配额与超时行为 每秒与每日上限各是多少、超过会返回什么、上游超时的时候是返回错误还是返回「无备案」。最后这一项最容易在上线之后才踩到。

小结

这组测试里最值得记住的不是分数,是一种失败的形状:报告成功、字段有值、值是错的。它不会让程序报错,所以不会有人发现;它会安静地把「查询失败」四个字写成某个域名的备案号。查得到百度证明不了什么,拿确定没有备案的域名去测,反而更容易看出一个工具能不能用。

备案状态本身也不是查一次就固定的——接入商取消接入、专项核查注销,都可能让它在毫无征兆的情况下消失。如果您正在评估备案域名,或要把备案查询接进自己的流程,欢迎把实际情况告诉我们一起看。

参考资料