每个抓取仪表盘都有一个成功率,而它们几乎都在统计同一件事:返回HTTP 200的响应数。这是一个容易采集、也容易让人安心汇报的数字。但它同时也是网络数据采集中最具误导性的数字,因为200只代表服务器返回了某些内容,并不能说明返回的是你所请求的页面。
这两者之间的差距,就是隐性失败率:在“成功”的请求中,实际返回了错误内容的比例。这是你在日志中看不到的失败,它混入数据集时,看起来和正常数据一模一样。
那么它的规模有多大?诚实的回答是:没有人发布过这方面的数据。这一空白本身就是最有意思的发现,本文接下来将说明这一空白为何存在、相近的测量结果显示了什么,以及你该如何测量自己的隐性失败率。
关键要点
- 目前没有任何已发布的研究测量过,在整个网络范围内,有多少比例的HTTP 200响应携带了错误内容。最新的大型反爬虫拦截研究明确写明,200响应中的内容劣化问题不在其研究范围之内。
- 拦截很普遍,但标记方式很混乱。一项针对Common Crawl的研究发现,至少有1.68%的网站明确拒绝了该爬虫,且状态码的使用不一致,甚至存在错误使用的情况。
- 拦截页面确实会以200状态返回。在2023年一项针对古巴的测量中,395个提供拦截页面的域名中,有32个使用了200状态码。
- 主要的链接失效研究将软404页面计为“存活”,因为核查内容比核查状态码要困难得多。
- 你自己的隐性失败率是可以测量的,但前提是验证内容,而不是验证状态码。
什么算作隐性失败
隐性失败是指任何报告成功、但内容并非真实访问者本应收到的响应。常见形式包括:
| 形式 | 你收到的内容 | 为何会被判定为成功 |
|---|---|---|
| 以200返回的拦截页面 | 本应是页面的地方出现了拒绝访问信息 | 状态码显示OK |
| 验证或过渡页面 | CAPTCHA或“正在检查你的浏览器”页面 | 通常是200,有时是错误码 |
| 软404 | 已不存在的内容返回了通用页面或首页 | 服务器返回200而非404 |
| 空壳页面 | 没有内容的HTML,因为页面靠JavaScript自行构建 | 一个完整、有效的文档 |
| 同意弹窗或付费墙 | 内容前面出现同意屏幕 | 页面加载了,内容却没有 |
| 错误的变体 | 另一个国家的页面、价格或语言 | 一个完全真实的页面,只是不是你想要的那个 |
以上每一种情况在解析、存储和汇总时都表现得像正常数据,没有一种会触发错误警报。
一个无人测量过的数字
研究反爬虫拦截和网页衰退问题的研究者们,反复回避了这个问题,并且有几位明确说明了这一点。
最新的大型研究,Gundelach、Mühlhauser和Herrmann(班贝格大学,2026年6月)的《Detecting Bot Detection》,在2026年2月27日至3月2日期间,在多种浏览器配置下扫描了Tranco排名前10,000的网站。其局限性部分直言不讳:“HTTP 200响应内的内容劣化问题不在我们的观察范围之内。”作者还调查了81篇网络测量论文,发现“只有5%的论文明确量化了反爬虫检测或拦截率,83%的论文完全未讨论这一问题”。
他们并不孤单。PAM 2025关于Common Crawl拒绝情况的研究,是基于非200响应展开的。2018年的全球地域拦截研究指出,一个网站可能加载成功,但“登录按钮消失了,或者某些内容不可用”,并将这些“更细微的内容变化”留给未来的研究去解决。皮尤研究中心2024年的链接失效研究,将“我们无法保证内容确实存在的模糊情形,比如软404页面”视为可访问。互联网档案馆2026年4月的死网研究“依赖HTTP状态码,并未检查页面内容以核查是否存在软404”。
这些都不是疏忽。对状态码进行分类可以扩展到数百万个页面;而判断内容是否正确,则需要知道每个页面“正确”的样子是什么。这正是隐性失败率在网络规模上无法被测量的原因,也正是它在你自己的目标站点上可以被测量的原因,因为在那里,你确实知道“正确”长什么样。
相近的测量结果显示了什么
没有单一数字能回答这个问题,但有几项测量结果为其划定了范围。
| 发现 | 来源 | 测量时间 |
|---|---|---|
| 无头Chromium在15.2%的顶级网站上遭到软拦截,而其他浏览器配置的比例为6.8%至7.2%;81.9%的被软拦截网站被归因于反爬虫检测 | Gundelach、Mühlhauser和Herrmann,arXiv,2026年6月 | 2026年2月至3月 |
| 至少1.68%的网站明确拒绝了Common Crawl,状态码使用不一致,甚至存在错误使用;80%的拒绝域名会拦截每一次请求 | Ansar、Sperotto和Holz,PAM 2025 | Common Crawl快照,2023年末 |
| 在向古巴用户提供拦截页面的395个域名中,有32个使用了200状态码 | Ablove等人,USENIX Security 2024 | 2023年5月 |
| 自动化爬取遗漏了真实用户遇到的45%的指纹识别网站,部分原因是未能通过反爬虫检测 | Annamalai、Bilogrevic和De Cristofaro,WWW 2025 | 30名用户,历时10周 |
| 在45,000个网站中,0.6%设有Cookie墙,德国排名前1,000的网站中这一比例为8.5% | Rasaii、Gosain和Gasser,IMC 2023 | 2023年 |
| 7.35%的网络服务器对未知文档返回200,而非404 | Prieto Álvarez、Álvarez Díaz和Cacheda Seijo,2014年 | 2014年之前 |
| 软404占失效链接的比例超过15% | Bar-Yossef、Broder、Kumar和Tomkins,WWW 2004 | 2004年之前 |
前两行描述的是通过错误码可见的拦截,这一部分很容易被发现。第三行则说明另一部分确实存在:在那项研究中,大约每十二个拦截页面中就有一个是以“成功”的面貌出现的。软404的数据已经比较陈旧,但它们也是目前为止已发布的最新数据。
它给下游带来的代价
关于隐性失败在真实数据集中造成的影响,最清晰的例子来自官方统计数据。英国国家统计局(ONS)在试行基于网络抓取超市数据的价格指数时,其2016年5月的更新报告称,“经过这一验证步骤后,被归类为异常或分类错误的产品总占比为25%”,价格数据“从340万条降至250万条”。报告还补充说,数据缺失“主要是由零售商对其网站进行结构性调整所导致”。
这25%并不是HTTP层面的失败率。其中大部分是被抓取到错误类别的产品,以及异常价格。这正是问题的关键所在:这些记录中的每一条都来自一次“成功”的请求,而其中四分之一却是不可用的。要发现它们,需要一个由统计机构专门建立的验证步骤。
为何状态码无法承载这一信号
如果服务器能诚实地报告拒绝访问的情况,那自然再好不过。但证据表明,它们做不到这一点的一致性。Common Crawl的研究发现,拒绝访问是通过不一致、甚至错误使用的HTTP状态码来传达的。古巴的研究发现,拦截分布在DNS故障、超时、403、少量专用的451代码,以及200状态码之中。
一些基础设施确实有所帮助。Cloudflare会为其所有类型的验证页面设置cf-mitigated: challenge响应头,这比状态码可靠得多。请检查这一响应头。但单一供应商的响应头并非网络标准,大多数隐性失败根本不带任何标记。
测量你自己的隐性失败率
其定义很简单:在你的系统判定为成功的响应中,未通过内容验证的比例。真正的工作在于验证本身。
- 验证记录,而非响应。 确定每种页面类型的每条记录必须包含哪些字段,凡是未产出这些字段的200响应都判定为失败。
- 对比页面类型的正常大小。 一个产品页面如果突然只有平时大小的五分之一,那它很可能根本不是产品页面。
- 寻找拦截和验证标记,包括像
cf-mitigated这样的响应头,以及你的目标站点实际使用的措辞。 - 运行金丝雀检测。 通过与生产环境相同的路径,抓取你独立确知其正确内容的页面,并进行比对。
- 记录你的抓取来源。 只有在你记录了访问点的情况下,才能检测出错误的国家变体,这也是vantage-point standard所提出的观点。
- 抽样进行人工审核。 每周由人工阅读几十条响应,可以捕捉到任何规则都未曾预料到的失败模式。
一个初步的分类器可以非常简单:
BLOCK_MARKERS = ("captcha", "access denied", "unusual traffic", "verify you are human")
REQUIRED_FIELDS = ("title", "price")
def classify(resp, record, baseline_bytes):
"""Label one response. Anything but "ok" on a 200 is a silent failure."""
if resp.headers.get("cf-mitigated") == "challenge":
return "challenge"
if resp.status_code != 200:
return "http_error"
if not record and any(m in resp.text.lower() for m in BLOCK_MARKERS):
return "block_page"
if len(resp.content) < 0.2 * baseline_bytes:
return "too_small"
if not record or any(record.get(f) in (None, "") for f in REQUIRED_FIELDS):
return "missing_fields"
return "ok"
按目标站点和页面类型分别报告结果,与你已有的成功率并列展示。当这两个数字出现分歧时,说明成功率在骗你。某个站点上软拦截数量的上升,也是它开始针对你的爬虫的最早迹象之一,这正是目标健康评分所要捕捉的问题。更全面的指标可参见如何监控网络抓取管道。
工具能帮上什么忙,又帮不上什么忙
托管式采集能在部分隐性失败到达你之前就将其消除。Shifter的Web Scraping API会自动重试失败的抓取、CAPTCHA以及目标站点的临时性错误,最多使用不同代理重试三次,并且只对成功的请求计费。JavaScript渲染消除了那些依赖浏览器自行构建内容的页面所带来的空壳问题,而extract_rules会返回命名字段,使缺失字段更容易被检测出来。
任何采集层都无法做到的是,识别一个格式完全正确的页面是否包含了错误的价格或错误国家的目录。只有你自己知道,对于你的数据来说,“正确”应该是什么样子。无论页面是通过何种方式抓取的,内容验证都应当是你数据管道中必不可少的一环。
结论
200只是服务器发出的一种声明,而不是对内容的保证。拦截页面、验证页面、软404、空壳页面、同意墙以及错误的变体,全都会以“成功”的面貌出现,而出于合理的现实原因,已发布的研究几乎测量了关于网络拦截的一切,唯独没有测量这一点。
由此带来的结果是:你唯一能拥有的隐性失败率,就是你自己测量出来的那个。验证每一条记录,保留你确知答案的金丝雀检测项,并将结果与你的成功率放在同一个仪表盘上展示。这两个数字之间的差距,就是你目前无法信任的那部分数据。
来源与参考文献
- Gundelach、Mühlhauser和Herrmann,Detecting Bot Detection: Prevalence, Techniques, and Implications for Web Measurement Research,arXiv,2026年6月12日。扫描时间为2026年2月27日至3月2日。
- Ansar、Sperotto和Holz,Web Crawl Refusals: Insights From Common Crawl,PAM 2025,2025年3月7日。
- Ablove等人,Digital Discrimination of Users in Sanctioned States: The Case of the Cuba Embargo,USENIX Security 2024。测量时间为2023年5月。
- McDonald等人,403 Forbidden: A Global View of CDN Geoblocking,ACM IMC 2018。
- Annamalai、Bilogrevic和De Cristofaro,Beyond the Crawl: Unmasking Browser Fingerprinting in Real User Interactions,WWW 2025。
- Rasaii、Gosain和Gasser,Thou Shalt Not Reject: Analyzing Accept-Or-Pay Cookie Banners on the Web,ACM IMC 2023。
- Prieto Álvarez、Álvarez Díaz和Cacheda Seijo,Soft-404 Pages, a Crawling Problem,Journal of Digital Information Management,2014年。
- Bar-Yossef、Broder、Kumar和Tomkins,Sic Transit Gloria Telae: Towards an Understanding of the Web’s Decay,WWW 2004。
- 皮尤研究中心,When Online Content Disappears: methodology,2024年5月17日。
- Sawood Alam,互联网档案馆,Gone but Not Forgotten: Recovering the Dead Web,2026年4月23日。
- 英国国家统计局,Research indices using web scraped data: May 2016 update,2016年5月23日。
- Cloudflare,Detect a Challenge Page response。
- Shifter,Web Scraping API errors and limits。