向搜索引擎发送几个请求,什么都不会发生。以脚本的方式发送几千个请求,在某个时刻响应就会发生变化:先是减速,然后是验证页面,最终是彻底封锁。Google、Bing 和 Yahoo 等搜索引擎在网络上运行着最成熟的机器人检测系统,而它们这样做,正是因为其结果页面是自动化采集的持续目标。
本文逐信号地解释搜索引擎如何检测爬虫:它们监控的请求速率、评分的 IP 信誉、读取的请求头和指纹,以及它们期望真实浏览器呈现的行为。读完本文,你将理解为什么朴素的爬虫会被如此迅速地标记,每项防御实际上在测量什么,以及合法的数据收集如何保持在正确的界限内。
搜索引擎首先为什么要封锁爬虫
搜索引擎结果页面 (SERP) 的生产代价高昂,而采集其价值不菲,因此运营者有强烈的动机来限制自动访问。他们的服务条款通常明确禁止直接抓取 SERP,除了政策问题,还有一个实际问题:大量自动化流量与真实用户竞争容量。为了同时保护两者,他们将多个检测信号层叠在一起。没有任何单一检查来决定你是否是机器人。每个信号贡献一个分数,一旦足够多的信号一致,你就会被限速、用 CAPTCHA 挑战,或直接封锁。
对于任何构建爬虫的人来说,重要的结论是:通过一项检查还不够。你可以完美地轮换 IP,却仍然在请求头上被抓住;你可以设置完美的 User-Agent,却仍然在请求速率上被抓住。以下各节逐一介绍主要信号,让你看到每个信号在寻找什么。
请求速率与请求量
第一个也是最廉价的信号,就是有多少请求到达、速度多快以及多有规律。真实浏览搜索结果的人产生的是缓慢、不规则的请求流,中间有停顿供其阅读。爬虫产生的是快速、均匀的流,没有任何停顿。当某个来源在短时间窗口内发送的请求数量远超正常人所能发出的,这个突发就是一个明显的信号,通常也是触发第一个 CAPTCHA 的因素。
完全均匀的时序本身也是一个漏洞。恰好每隔 500 毫秒发送一个请求,比以不均匀方式分布的相同总量更明显地表现出机械化特征。速率限制和请求节流位于此之上:搜索引擎在时间框架内追踪每个来源的请求,一旦数量超过阈值,就开始减慢或拒绝响应。这就是为什么逐渐增加、带抖动的请求时序,远比原始速度更重要的原因。
IP 信誉与数据中心地址段
每个请求都带有源 IP,搜索引擎甚至在查看请求内容之前就对该地址评分。两件事驱动评分。首先是行为:最近发送了看起来像自动化流量的 IP 比没有发送过的 IP 信誉更差。其次是来源:该地址所属的网络说明了很多关于它是真实用户的可能性。
属于已知数据中心、托管、代理和 VPN 地址段的 IP 受到怀疑,因为真实消费者很少从这些地址浏览。许多这样的地址段被详细记录,实际上处于预先被标记的状态,因此从云服务器运行的爬虫在发出第二个请求之前就可能被过滤掉。住宅地址映射到普通家庭连接,看起来更加可信。这是 数据中心 vs 住宅代理 权衡的核心:相同的爬虫行为完全一样,但其流量的来源改变了该流量被判断的方式。共享和回收的地址还会继承之前用户留下的信誉。
缺失或异常的请求头和 User-Agent
真实浏览器在每个请求上发送一致的、可预测的 HTTP 请求头集合:完整的 User-Agent 字符串、Accept、Accept-Language、Accept-Encoding 等,以可识别的顺序排列。裸 HTTP 客户端发送更少的请求头,通常顺序不同,有时 User-Agent 默认就是库的名称。这些空缺中的每一个都是容易识别的漏洞。
User-Agent 是被监控最多的请求头,因为它最容易出错。保留默认值等于直接宣布爬虫的存在。为数千个请求设置单一固定的浏览器字符串更好,但仍然可疑,因为真实流量显示的是浏览器和版本的分布。轮换 User-Agent 有助于使请求看起来来自不同设备,但只有当其余请求头与所声称的浏览器保持一致时才有效。Chrome 的 User-Agent 配上任何真实 Chrome 安装都不会发送的请求头集合或 Accept-Language,就是一个矛盾,而矛盾正是检测系统所寻找的。
TLS 和 HTTP 指纹
在读取任何请求头之前,连接本身就留下了指纹。当你的客户端打开 HTTPS 连接时,它会发送一个 TLS Client Hello,以特定顺序列出它支持的密码套件、扩展和曲线。这个形态是客户端库和版本的特征,对其进行哈希运算会产生一个签名(通常称为 JA3 指纹)。Chrome 的握手看起来像 Chrome;Python HTTP 客户端的握手看起来像 Python,无论它后来声称什么 User-Agent。
这是任何请求头都无法修复的层,也是许多爬虫暴露自己的地方。你可以将每个请求头都设置成声称自己是浏览器,但如果你的 TLS 握手匹配脚本库,网络层和应用层就不一致了,比较两者的防御者立刻就能看到不匹配。同样的思路延伸到 HTTP 层:协商的版本、连接的多路复用方式以及低级帧的顺序,都添加了真实浏览器自然产生而简单客户端不会产生的细节。要深入了解这些设备级信号如何组合,请参阅我们关于 浏览器指纹识别 的指南。
行为模式与未执行 JavaScript
现代搜索页面运行 JavaScript,而该脚本同时做两件事:动态加载结果,并观察访客的行为。真实用户产生一系列行为信号,包括鼠标移动、滚动、焦点变化以及动作之间不规则的时序。仅获取原始 HTML 的爬虫不会产生任何这些信号。行为的缺失本身就是一个信号。
这里通常同时出现两种失败。第一种是根本不执行 JavaScript。许多结果是在页面加载后注入的,因此只读取初始 HTML 的客户端可能错过它来获取的数据本身,而且缺乏任何脚本执行将其标记为非人类。第二种是执行了 JavaScript,但行为表现机械:瞬时导航、无滚动、无光标、完全均匀的延迟。由 Puppeteer、Playwright 或 Selenium 驱动的无头浏览器可以渲染页面甚至模拟类人交互,这在一定程度上弥补了这一差距,但配置不当的无头浏览器会广播自己的自动化标志,并以不同的方式被抓住。如果你的目标严重依赖客户端渲染,我们关于 抓取 JavaScript 网站 的指南涵盖了相关机制。
蜜罐链接
有些防御不等爬虫不当行为;它们主动诱导。蜜罐是放置在页面中的链接或表单字段,使人类永远看不到或不会跟随它,用 CSS 隐藏、放置在屏幕外,或以真实浏览器遵从的方式标记。视觉导航的人完全跳过它。爬取 HTML 中每个锚点的爬虫会跟随它,而这单一的点击就揭示了访客读取的是原始标记而不是渲染页面。一旦某个来源触发了蜜罐,搜索引擎就对其自动化有了高度信心,可以直接采取行动。
上面的每个信号都指向同一个结论:通过一项检查还不够,而手动保持所有信号一致是困难的部分。Crawling API 将其作为单次托管请求处理。它渲染 JavaScript,轮换真实用户 IP 使你的来源读起来像住宅地址,呈现一致的请求头和匹配的指纹,并处理 CAPTCHA 挑战,因此你只需指向单个端点就能获得解析后的数据,而不是拦截页面。在免费层级试用它。
CAPTCHA 挑战
当上述信号累积到足够的怀疑但尚未确定时,搜索引擎不会直接封锁,而是要求访客证明自己是人类。reCAPTCHA 或图片挑战对真实用户来说代价低廉,对脚本来说代价高昂。CAPTCHA 不是随机的:它们由已经介绍过的相同模式触发,包括高请求速率、较差的 IP 信誉、缺失的浏览器请求头以及不连贯的指纹。换句话说,CAPTCHA 通常是你之前触发的检测信号的可见结果。
对于合法抓取,正确应对 CAPTCHA 的方式不是强行破解,而是理解它为什么出现并消除原因:放慢速度、改善来源、修复请求头。解决服务存在并有其用处,但不断遇到挑战的爬虫是一个上游信号需要关注的爬虫。我们在关于 在网络抓取中绕过 CAPTCHA 的指南中更深入地探讨了原因和方法。
这里几乎每项防御都本质上是一个一致性检查。IP、请求头、TLS 握手、渲染行为和请求速率都必须描述同一个合理的用户。爬虫很少因为单一信号被发现;它被发现是因为它的两个信号相互矛盾。
这对合法抓取意味着什么
这并不意味着搜索数据对合法收集者而言是禁区。这意味着朴素的方法(用默认请求头从云服务器发起快速循环的原始 HTTP 请求)几乎同时触发了每一个信号,并迅速失败。可靠的收集之所以有效,是因为它保持每个信号的一致性:住宅级 IP 以合理方式轮换使任何单个来源都不承担全部负载,完整一致的请求头集合与所声称的浏览器相匹配,与这些请求头一致的指纹,JavaScript 被渲染使动态结果真正出现,以及看起来像人而不是节拍器的请求速率。
手动保持所有这些一致是真正的工程工作,而且并非一劳永逸,因为检测会进化,浏览器版本也在更新。这就是托管方法所填补的空缺。一个为你维护 IP 池、渲染、指纹一致性和挑战处理的服务,将一个持续变化的维护问题转化为单个端点。关于在搜索引擎及其他目标上保持不被拦截的更广泛攻略,在我们关于 如何在不被拦截的情况下抓取网站 的指南中。
负责任地抓取
检测规避是一个技术话题,但负责任的收集才是让它可持续的东西。尊重每个网站的服务条款和 robots.txt 指令,并记住搜索引擎的条款通常限制对 SERP 本身的抓取。优先使用公开数据,避免登录或付费墙后面的任何内容,也不要收集你没有处理依据的个人数据。将请求速率保持在合理水平,这样你就不会降低真实用户的服务质量;在预期的情况下诚实标识你的流量;并积极缓存,这样你就不必重新获取相同的页面。以礼貌的节奏收集不仅是道德上的选择,也是最不可能被拦截的选择。
核心要点
- 检测是分层的。 搜索引擎同时评分许多信号,当足够多的信号一致时才采取行动,因此通过单一检查不足以保持安全。
- 速率和来源最先被检测。 突发请求量和数据中心或代理 IP 是最便宜、最快速的标记方式,通常在内容被读取之前就已发生。
- 请求头和指纹必须一致。 浏览器 User-Agent 配上脚本库的 TLS 握手或稀薄的请求头集合,是一个暴露爬虫的矛盾。
- 行为和 JavaScript 很重要。 没有脚本执行、没有滚动、机械化时序以及跟随蜜罐,都将访客标记为自动化;CAPTCHA 通常是其中某个的可见结果。
- 一致性是目标。 可靠、负责任的收集保持 IP、请求头、指纹、渲染和节奏的一致,这正是托管方法为你处理的内容。
常见问题
搜索引擎如何检测爬虫?
它们结合多个信号:请求到达的数量和速度、源 IP 的信誉和网络来源、请求头和 User-Agent 是否匹配真实浏览器、连接的 TLS 和 HTTP 指纹、是否执行了 JavaScript 以及是否存在类人行为、蜜罐链接,以及 CAPTCHA 挑战。没有单一检查来决定结果。一旦足够多的信号指向自动化,访客就会被限速、挑战或封锁。
为什么我的爬虫即使使用了好的代理也会被封锁?
因为 IP 只是众多信号之一。如果你的来源是干净的,但你的请求速率表现机械,你的请求头稀薄,或者你的 TLS 握手说你是脚本库而你的 User-Agent 声称是浏览器,其他信号仍然会标记你。检测从整体上看,并对层与层之间的矛盾做出反应,而不是孤立地看 IP。
数据中心和住宅 IP 用于抓取有什么区别?
数据中心 IP 属于托管提供商和云网络,真实消费者很少从这些地址浏览,因此它们被广泛预先标记,被评为可疑。住宅 IP 映射到普通家庭连接,看起来更加可信。相同的爬虫从任何一种地址行为都完全相同,但其流量根据它看起来来自哪里被判断不同。
爬虫为什么会触发 CAPTCHA?
CAPTCHA 是较早检测信号的可见结果。高请求速率、较差的 IP 信誉、缺失或不一致的浏览器请求头,以及不连贯的指纹,都会引发足够的怀疑,以提示挑战而不是直接封锁。持久的修复是解决上游原因,而不仅仅是解决挑战,因为不断遇到 CAPTCHA 的爬虫有需要关注的信号。
什么是蜜罐链接?
蜜罐是放置在页面中的链接或表单字段,使人类永远不会与之交互,用 CSS 隐藏、移至屏幕外,或对渲染视图不可见。真实访客跳过它;爬取原始 HTML 中每个锚点的爬虫会跟随它。这单一行动揭示了访客读取的是标记而不是渲染页面,给网站提供了高度信心认为流量是自动化的。
负责任地抓取搜索引擎是否可能?
可以,通过以合理节奏收集公开数据,尊重服务条款和 robots.txt,避免个人或付费墙后的数据,缓存以防止冗余请求,以及不降低真实用户的服务质量。负责任的收集和可靠的收集往往是一致的:礼貌且一致的流量也是最不可能被标记的。
大规模爬取任何站点,无需与基础设施对抗。
Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。
