我们的立场如下:我们是 Geonode,从事代理服务销售,因此出于商业利益,我们站在爬虫这一边。 坦率地说,大多数蜜罐规避措施其实只是规范地进行爬取,而最有效的措施之一完全无需成本:遵守 robots.txt。 大部分陷阱都设置在网站已明确要求爬虫不要访问的路径上,因此合规的爬虫永远不会遇到它们。 其余的则可通过渲染 CSS、不提交未经邀请的表单以及限制爬取范围来规避。这些都不需要从我们这里购买任何东西,而一个需要依赖代理才能躲过蜜罐的爬虫,其实早已犯下了更根本的错误。
什么是蜜罐陷阱
其定义更多是行为层面的,而非技术层面的:这是一种只有自动化客户端才会与其交互的内容,放置该内容的目的是通过这种交互来识别该客户端是否为自动化程序。
这一逻辑很简单,且难以反驳。 人类访客使用浏览器,浏览器会应用 CSS、渲染布局,并向用户展示可见内容。而解析 HTML 的爬虫则会一视同仁地看到标记中的所有内容——包括样式设置为不可见的链接、隐藏在屏幕外的表单字段,以及在人类视线范围内没有任何链接指向的路径。
与其中任何一项进行交互都是一个强有力的信号。虽然这并非决定性证据——毕竟辅助技术工具和文本模式浏览器的行为也各不相同——但其信号强度足以让网站采取相应措施。
具体后果因网站而异。有些网站会记录并忽略;有些会实施速率限制;有些会屏蔽该地址;有些则会无限期提供降级内容——这是最糟糕的结果,因为这看起来像是成功了;还有些网站现在会采取更复杂的措施,下文将对此进行说明。
你可能会遇到的六种情况
1. 隐形链接。 采用 display: none、visibility: hidden 样式,或设置为零尺寸、与背景色相同,抑或定位在屏幕外的链接。这些链接存在于 HTML 中,但在渲染后的页面上不可见。
<a href="/trap/do-not-follow" style="display:none">Products</a>
<a href="/hidden" class="visually-hidden">Sitemap</a>
这是最常见的形式,也是最容易避免的。
2. 禁止访问的路径。 仅出现在 robots.txt 文件中、位于 Disallow 指令下、且没有任何地方链接到的 URL。发现此类路径的唯一方法是阅读排除文件并将其忽略——这使得对该路径的请求几乎可以被视为蓄意违规的明确信号。
3. 隐藏表单字段。 通过 CSS 隐藏且用户绝不会填写的字段。任何包含该字段值的提交都来自解析 HTML 的程序。常见于评论表单和注册流程中,作为一种合法且有效的反垃圾邮件措施。
4. 无限的 URL 空间。 并非总是故意的,但无论如何都会造成同等程度的损害。一个带有“下个月”链接的日历会生成无限的 URL。大型目录中的多维导航会产生组合爆炸。一个没有深度和模式限制的爬虫会一直追踪这些链接,直到被某种东西阻止为止。
5. 时序陷阱。 需要延迟后才显示的内容,或者拒绝处理速度超过人类操作速度的表单提交。这些机制会拦截即时响应的客户端,而非解析标记的客户端。
6. 恶意或生成的内容。 这是最新出现的一类,其重要性足以单独成章。
AI 陷阱与生成迷宫
这是一项真正的新进展,也是该话题在过去几年中发生转变的原因。
Cloudflare 的 AI 迷宫 是最广泛部署的示例。Cloudflare 将其描述为“一种利用 AI 生成的内容来拖慢 AI 爬虫速度、迷惑其行为并消耗其资源的新型缓解方案”。
其工作原理如下:Workers AI 生成涵盖各类主题的多样化 HTML 页面,并存储在 R2 中以实现快速分发;这些诱饵页面通过隐藏链接与真实页面相连,这些链接“对人类访客不可见,但对机器人爬虫却可访问”。
Cloudflare 对该方案为何有效的阐述,是对“蜜罐原理”最精辟的阐释:
没有真正的人类会深入点击四层链接,钻进由 AI 生成的无意义内容迷宫中。
关键在于,所提供的内容“真实且与科学事实相关,只是与被爬取的网站无关,也非该网站的专有内容”——因此爬虫无法通过检查文本是否连贯来识别它。这些内容确实连贯,只是讲述的是其他内容。
该功能在所有 Cloudflare 套餐(包括免费套餐)中均可用,只需在机器人管理部分点击一个开关即可启用,且“无需额外配置”。
独立工具也基于相同原理运作。Nepenthes 会生成一个没有出口链接的无限页面迷宫。 Iocaine 作为反向代理运行,并采取了一个值得了解的额外步骤:它会“毒化”所提供的 URL,因此,即使爬虫后来伪装成浏览器返回,仍可通过其请求队列中仅包含“陷阱”曾分发的 URL 这一事实被识别出来。这是一种持久的标记,而非瞬时的标记。
这对任何运行爬虫的人都有两点启示。
通过内容质量进行检测是行不通的。 这些页面内容连贯且符合事实。其识别特征在于:它们与网站无关,无法通过任何人类可发现的链接访问,且数量无穷无尽。
限制爬取范围如今已非可有可无,而是必不可少。 若爬虫未设置深度限制、页面数量限制及重复检测机制,可能会在生成无意义内容的过程中耗费数天的计算资源和数吉字节的计费带宽,且全程不会收到任何错误提示。在按吉字节计费的模式下,这无异于为一无是处的操作支付了真金白银的账单。
如何在不耍花招的情况下规避这些陷阱
这里提到的每项措施,本就是一款设计良好的爬虫理应做到的。
遵守 robots.txt。 仅此一项就能避开大部分陷阱,因为网站通常会将禁止访问的路径放在该文件中。这现已成为一项标准——RFC 9309——其匹配规则基于特异性而非顺序,关于如何正确解读该文件,我们已在如何阅读 robots.txt 文件中详细说明。
在跟随链接之前,请检查计算出的可见性。 在无头浏览器中,这很简单:
const links = await page.$$eval('a[href]', els =>
els.filter(el => {
const s = getComputedStyle(el);
const r = el.getBoundingClientRect();
return s.display !== 'none' && s.visibility !== 'hidden' &&
parseFloat(s.opacity) > 0 && r.width > 1 && r.height > 1;
}).map(el => el.href)
);
请注意使用 getComputedStyle 而不是读取内联的 style 属性——被样式表规则隐藏的链接没有内联样式可供检查。
在没有浏览器的情况下,请应用启发式规则:跳过内联样式中包含 display:none 或 visibility:hidden 的链接,跳过空锚文本,跳过诸如 hidden、visually-hidden 和 sr-only 之类的类名,并对 href 属性在可见文本中完全未出现的链接保持警惕。
对爬取范围进行绝对限制。 设定最大爬取深度、最大页面数量以及每个域名的爬取配额。这并非备用方案——而是硬性限制。这是应对无限空间的唯一有效防御措施,无论这些空间是如何生成的。
检测重复内容。 内容哈希可识别那些表面上略有差异的生成页面。 URL 模式分析可捕获无限增长的路径。如果某个目录已生成两百个页面且没有结束的迹象,请立即停止并仔细检查。
**不要提交未经邀请的表单。**隐藏字段陷阱只会捕获那些填满所有找到的输入框的客户端。
实施速率限制并控制节奏。 模拟人类的请求间隔可规避时间陷阱,同时降低其他所有信号的强度。
表明身份。 带有名称和联系 URL 的爬虫,其操作员可以选择允许其访问。这虽不完全是规避陷阱的措施,但会改变你触发陷阱后的处理方式。
如何在实际环境中识别陷阱
以下是表明你已误入陷阱的迹象,按其出现速度从快到慢大致排序。
页面计数无法收敛。 队列持续增长而非缩减,这是最早出现的预警信号,也是最容易通过监控工具检测到的。
内容连贯但毫无关联。 页面读起来顺畅,却与网站的实际主题毫无关系。这是“AI迷宫”的典型特征。
URL 遵循生成的模式。 路径冗长、分段结构异常,且不存在真实网站应有的重复 URL。
没有任何合理来源的入站链接。 页面之间相互链接,但没有任何外部链接指向该网站。
响应时间可疑地一致。 生成的内容来自缓存;真实页面的响应时间则存在波动。
数据质量下降,但错误率保持不变。 这是最明显的后期信号,也是为何所有请求都返回 200 状态码至关重要的原因。
实际的控制措施应是持续的断言,而非手动检查:如果在爬取过程中,新发现的 URL 与已抓取页面之比没有下降,说明有某种机制正在以比你处理速度更快的速度生成 URL,而任何有限规模的网站在爬取过程中都不会出现这种情况。
致网站所有者:部署方法
简要说明另一方面,因为相同的理解对双方都适用。
隐藏表单字段是性价比最高的方法。 添加起来非常简单,能有效防止自动表单提交,且不会影响真实用户。给该字段起一个不起眼的名称,通过样式表中的 CSS 将其隐藏(而非内联样式),并拒绝任何填写该字段的提交请求。
隐藏链接可拦截不渲染页面的爬虫。 这种方法很有效,建议配合 robots.txt 中的“disallow”指令使用,以免合规的爬虫被误拦截。因未排除的陷阱而惩罚行为良好的爬虫,实属自找麻烦。
受控陷阱现已成为可开关功能。 Cloudflare 的该功能在所有套餐(包括免费套餐)中均可用,且无需配置,因此任何网站都能轻松使用。
无障碍性才是真正的限制因素。 屏幕阅读器和文本浏览器不会像明眼用户浏览器那样应用视觉样式。 使用display: none设置的陷阱通常是安全的,因为辅助技术会尊重该标记;而使用屏幕外定位或透明文本设置的陷阱可能会被屏幕阅读器用户识别,导致用户跟随链接并被阻挡。若部署此类陷阱,请务必使用屏幕阅读器进行测试。
并明确您真正想要什么。 搜索引擎、比价合作伙伴、无障碍工具、监控服务和人工智能代理都会发送自动化流量,其中部分正是您所需要的。一刀切的陷阱会拦截所有流量。通过用户代理排除已知良性爬虫,并仅在 robots.txt 已禁止的路径上设置陷阱,这种安排既能拦截您不希望的流量,又能放行其余流量。
何时该停止而非适应
这一点值得明确说明,毕竟我们是一家以“适应”为主要产品的供应商。
如果某个网站部署了防护措施,这就已经传达了一个明确的信息。结合robots.txt的禁止条款以及禁止自动化访问的规定,这一信息毫无疑问,而继续试图绕过这些限制,其后果将远不止于技术层面。
其他替代方案通常更好,而且几乎总是更经济:
主动询问。 发送一封邮件说明您的身份和需求,往往比人们预期的更容易解决问题;而通过合作伙伴数据源获取数据,则能彻底消除这一问题。
查看是否有官方 API。 许多采取严格保护措施的网站也会发布官方 API,这正是为了给合法用户提供可行的途径。
查看数据是否存在于其他地方。 公共数据集、档案库、官方备案文件、授权数据提供商。
缩减需求范围。 许多数据抓取行为收集的数据远超实际需求。需求越小,越容易通过合法途径满足。
还有一点很关键:陷阱的设计初衷就是让你付出的代价远高于网站自身承受的成本。Cloudflare 只需生成页面一次,随后从存储中提供服务;而你却要按每千兆字节、每计算小时以及工程师工时付费。这种成本不对称是刻意为之的,无论你付出多少努力都无法改善。
大家还问
网页爬取中的“蜜罐陷阱”是什么?
指放置在页面上、仅供自动化客户端交互的内容——例如不可见的链接、隐藏的表单字段,或是链接到人类用户绝不会查看的位置的路径。 与之交互会将该客户端识别为机器人,网站会通过记录日志、限流或封禁等方式进行应对。
如何避免蜜罐陷阱?
请遵守 robots.txt 规范,因为许多陷阱都设置在被禁止的路径上。在跟随链接之前,请检查计算后的可见性,而不是解析原始 HTML。 不要填写未显示的表单字段。并为爬取设置严格的深度和页面数量限制,这是防范无限空间的唯一防御手段。
什么是 AI 陷阱?
一种向自动化爬虫提供无尽迷宫般生成的页面,以消耗其资源的系统。 Cloudflare 的 AI Labyrinth 会生成连贯且基于事实的内容,这些内容与网站本身毫无关联,并通过真实页面上的隐形链接进行引导。该功能在所有套餐(包括免费套餐)中均可使用,只需点击一个开关即可启用。
我能在掉入蜜罐之前检测到它吗?
部分可以。渲染页面并检查计算出的样式可以可靠地捕获隐藏链接。但对于生成的迷宫则更为困难,因为内容具有连贯性——相关信号包括不断增长的队列、与网站无关的内容,以及不重复的 URL 模式。无论如何,限制爬取范围都是行之有效的防御措施。
隐藏链接会损害 SEO 或无障碍访问吗?
从历史上看,搜索引擎一直将隐藏文本视为操纵行为,因此陷阱通常会配合 robots.txt 指令进行屏蔽。无障碍访问才是更大的问题:辅助技术会尊重 display: none 指令,但屏幕外或透明的文本可能会被屏幕阅读器用户识别并朗读出来,导致用户误点。
如果我的爬虫触发了蜜罐会怎样?
情况各不相同。有些网站会记录该事件,有些会实施速率限制,有些会屏蔽该地址,还有些会无限期地提供降级内容——这是最糟糕的情况,因为所有请求都返回 200 状态码,而您的数据却在悄无声息地退化。 而“沥青坑”(Tarpits)的做法则不同:它们会永远向你提供内容。
蜜罐陷阱是否合法?
在自己的网站上设置蜜罐完全合法——你决定提供什么内容。 网站如何处理由此获得的识别信息,则受其服务条款约束。从爬虫的角度来看,触发蜜罐本身并不违法;但这可能违反服务条款,属于合同范畴。
如何防止我的爬虫在沥青坑上浪费资金?
对每个域名的爬取深度和页面数量设置硬性限制,对内容进行哈希处理以检测近似重复页面,并在新发现 URL 与已抓取页面之比未能下降时触发警报。如果没有这些措施,一个受流量限制的爬虫可能会在生成的页面上耗费数天时间和数千兆字节的流量,同时却报告完美的成功率。
总结
蜜罐陷阱基于一个假设:爬虫看到的是源代码,而人类看到的是渲染后的页面。其他所有情况都只是变体——一个不可见的链接、一个隐藏的表单字段、一个仅在 robots.txt 中提及的路径,或者一个永无止境的迷宫。
这些防御措施,无论如何都应是构建良好的爬虫本应具备的功能。请遵守 robots.txt 规范,因为许多陷阱就藏身于此,而遵守规范无需任何成本。 检查计算出的可见性,而非解析原始 HTML。除非表单被明确展示,否则不要触碰它们。并为爬取设定硬性限制,这是唯一能保护你免受那些内容被刻意设计成与真实文本无法区分的生成式迷宫侵害的措施。
最后这一类已改变了经济格局。一个受控的“陷阱”只需生成页面一次,随后便可从缓存中提供服务;而爬虫则需按每千兆字节和每计算小时付费,却每次都只收到 200 状态码。这种不对称性正是关键所在——如今任何网站只需切换一个开关即可启用该功能,且这种机制不会因投入更多精力而改变。
这使得这种看似不起眼的选项值得认真考虑。一个部署了陷阱的网站已经向你传递了某种信息,而请求数据源、检查API或从其他地方获取数据,通常比试图在技术上战胜一个早已设好局让你失败的对手更快、更便宜且更持久。
