我们的立场声明如下:我们是 Geonode,我们销售代理服务——而这正是大多数关于该主题的文章旨在推销的产品。按诚实排序,代理服务大约排在第六位,排在它前面的五项都是免费的。 通过合理控制爬行节奏、身份识别、缓存、遵守 Retry-After 以及阅读 robots.txt,所避免的封禁数量将远超任何形式的地址轮换,因为这些方法针对的是网站封禁爬虫的根本原因——负载和不可预测性——而非仅仅治标不治本。代理确实能解决一个具体问题,相关内容将在后文详述。若您首先依赖代理,不仅会白白花钱,最终仍会遭到封禁。
爬虫为何会被封禁
按发生频率从高到低排列的四个原因。
请求频率。 你在短时间内发出了过多的请求。这是最常见的原因,而且完全由你自己掌控。 当一个网站判定来自同一IP地址的每秒三十次请求构成问题时,它既不知道也不在乎你是谁。
不可预测性。 突发流量、对错误的反复重试、重复抓取同一页面、追踪无限的URL空间。网站无法预先规划的负载,比可预见的负载更令人头疼。
匿名性。 一个身份不明的客户端产生无法解释的流量,这是一种必须阻止的问题。而对于已识别的客户端,则需要做出决定,通常该决定是允许其访问。
身份信号。 IP地址类型、TLS指纹、请求头组成。 这些因素确实存在,但排在列表末尾,是因为它们主要在网站已决定不接受未识别的自动化请求后才显得重要——而且因为它们是最难诚实地进行调整的。
请注意,这四点中有三点涉及行为。业界对第四点的关注,源于其最易于推广,而非其是导致大多数封锁的主要原因。
从“无需爬取”开始
这是回报最高、却最常被忽略的措施。
检查是否提供 API。 许多网站都提供了 API,且这些 API 稳定、结构化且经过官方授权。对提供 API 的网站进行爬取,不仅工作量更大,结果却更差。
检查是否有合作伙伴或联盟数据源。 整个行业——招聘、房产、零售、旅游——都会专门为聚合网站发布批量数据源,因为聚合网站能为它们带来流量。在开发之前先询问一下。令人惊讶的是,许多网站都会同意。
**检查是否提供网站地图。**它不仅提供 URL 清单,还包含 lastmod 时间戳,因此你可以仅抓取更新内容,而非全部内容。
检查是否存在嵌入式结构化数据。 位于 <script type="application/ld+json"> 块中的 JSON-LD 专为机器可读而设计,即使网站重新设计也不会丢失,而且已经存在于你打算抓取的页面中。
检查数据是否存在于其他地方。 公共数据集、档案库、官方备案文件。
上述每一种方法都能彻底解决阻塞问题,而非仅仅缓解。先编写爬虫的惯性思维是该领域中最耗费资源的习惯,这也是我们将本节置于任何技术内容之前的原因。我们在如何查找网站上的所有页面中详细介绍了完整的源代码层次结构。
请先阅读规则
robots.txt 现已成为一项标准 RFC 9309,正确遵守该标准既符合规范要求,也符合自身利益。
运营中需要重点注意的部分:匹配依据的是特异性而非顺序——匹配规则最长的优先;5xx响应表示完全禁止,而非“继续执行”; 404 表示无限制;且该文件必须至少每 24 小时刷新一次,而非仅在启动时获取一次。
请使用经过维护的解析器。特异性规则和百分比编码规范化都容易出错,而误读该文件的爬虫会误以为自己符合规范,实则不然。我们在如何读取 robots.txt 文件 中详细探讨了这些细节。
然后请仔细阅读服务条款。robots.txt 并不代表授权——RFC 中已明确指出这一点——且网站可能禁止自动化访问,无论该文件允许与否。在开始之前了解这一点,总比收到一封通知信时才发现要好。
合理控制请求频率
这是价值最高且成本最低的技术措施。
每个域名每1至2秒发送一次请求是一个合理的默认设置。 对于小型网站应放缓频率;在没有证据表明目标服务器能够承受更频繁请求的情况下,切勿加快频率。
遵守 Crawl-delay 中的规定,前提是 robots.txt 已设置相关值。 这虽是标准的扩展而非组成部分,但遵守它既不花费任何成本,又能体现善意。
加入随机抖动。 间隔完全固定的请求是人类不会产生的特征。例如,将间隔随机化在 1.0 到 2.5 秒之间,即可在不增加成本的情况下消除这一特征。
按域名限制并发数,而非全局限制。 八个并发请求分散在八个域名上是礼貌的;而八个并发请求集中在一个域名上则不然。
尽可能在非高峰时段进行爬取。 网站在繁忙时段的容错能力较低,而夜间运行的任务不会产生额外成本。
**在增加处理能力前,先延长执行时间窗口。**这是最实用的思维转换方式:24 小时内爬取 5 万个页面大约需要 2 个并发连接;而在 2 小时内爬取相同的 5 万个页面则需要 20 个并发连接。如果任务的快速完成并不影响其他任何事情——而通常确实如此——那么调整时间安排就是你最经济的优化手段。 我们在你需要多少个代理一文中详细分析了相关计算。
表明身份
这虽有悖直觉,却始终行之有效。
User-Agent: AcmePriceBot/1.2 (+https://acme.example.com/bot)
一个名称、一个版本号,以及一个能让他人了解您是谁以及如何联系您的网址。三大优势,皆为事实:
**robots.txt
可以专门向您发送请求。** 规则是根据产品令牌进行匹配的,因此网站可以为您的爬虫授予其他爬虫无法获得的权限。如果您保持匿名,就无法实现这一点。
**网站管理员可以联系您,而不是直接封禁您。**这种情况比人们预期的要常见,而且远比三周后才发现被封禁要好得多。
这支持主动申请访问权限。 “我们是名为 AcmePriceBot 的爬虫;以下是我们收集的数据及其原因”——这样的沟通往往能取得实质性进展。
而另一种做法——复制 Chrome 的字符串——非但无法掩饰身份,反而会引发矛盾,因为在 TLS 指纹和请求头集明显不属于浏览器的连接中,浏览器用户代理反而比坦诚相告更容易被识别。我们在 使用 curl 设置自定义用户代理 一文中已对此进行过探讨。
缓存与使用条件请求
一种在不降低覆盖率的情况下减轻负载的措施。
切勿两次获取相同的未更改资源。 将已获取的内容及其ETag和Last-Modified值存储起来,然后发送条件请求:
curl -sS -H 'If-None-Match: "abc123"' https://example.com/page
一个 304 Not Modified 仅需几百字节,而非整页数据。在大部分页面未发生变化的重新抓取过程中,这能使您的带宽费用和目标服务器的负载都减少一个数量级。
利用站点地图中的 lastmod 规则 来决定需要抓取哪些页面。 一个拥有五万个页面的网站,如果今天只有两百个页面发生了变化,那么爬取范围应仅限于这两百个页面,而不是五万个页面。
存储原始响应。 当解析器出现故障时,应重新解析已有的数据,而不是重新抓取。这既能节省成本,也是对服务方的尊重。
正确去除 URL 重复项。 对尾部斜杠、查询参数顺序、主机名大小写进行标准化处理,并去除跟踪参数。未进行标准化的爬虫会多次访问同一页面,使其看起来比实际更像一个资源消耗巨大的客户端。
按服务器要求处理错误
服务器会告诉你该怎么做。遵循这些指示既正确,也是让系统恢复正常运行的最快途径。
429 Too Many Requests 在 RFC 6585 中被定义为表示“用户在给定时间内发送了过多的请求(‘速率限制’)”。响应“可能包含一个 Retry-After 头,用于指示在发送新请求前应等待多长时间”。
503 Service Unavailable 表示服务器“由于临时过载或计划内维护,目前无法处理该请求”,并且它“可能发送一个 Retry-After 报头字段……以建议客户端应等待的适当时间”。
Retry-After 根据 RFC 9110 的规定,可以是 HTTP 日期或秒数——Retry-After: 120 表示等待两分钟。
遇到 429 或 503 状态码时的正确处理方式:
停止向该域名发送请求。 不是减缓速度,而是完全停止,至少持续给定时间间隔。
如果未指定Retry-After,则采用指数退避,并设定一个宽松的起始值。
随后降低稳态请求速率,因为系统刚刚提示你当前速率过高。
**切勿立即重试。**在速率限制下频繁重试会导致临时限制演变为永久封禁,这也是爬虫过程中最常见的自损行为。
另请注意,RFC 6585 规定“带有 429 状态码的响应‘不得’被缓存存储”——因此缓存层无法防止你重蹈覆辙。
代理真正能派上用场的情况
尽可能准确地介绍我们自己的产品。
**在以下情况下,代理能提供帮助:**您已优化了请求速率,但仍需要单个地址无法提供的吞吐量; 您需要访问特定区域的内容,而关键在于让系统认为您位于某地;您运行分布式爬虫,并希望它们看起来像是独立的客户端,而非一台拥有多个线程的机器;或者您当前使用的IP地址声誉不佳,但这并非您的过错。
**以下情况代理无济于事:**您的请求速度过快——即使使用更多地址,请求速率相同,结果只会导致整个地址池被标记,而非单个地址;或者您的请求模式已被通过 TLS 指纹或标头组合识别出来,因为这些特征会随您一起传输。 此外,当网站条款禁止自动化访问时,增加IP地址也无济于事。
选择哪种类型: 大多数爬取任务应选择数据中心,因为其成本低得多,且公共网页通常无需更高配置——我们的数据中心服务起价为 0.14 美元/GB。 仅当数据中心方案明显无法满足需求,或您需要基于消费者网络的地理定位时,才升级至住宅网络,价格从 0.79 美元/GB 起。数据来自我们的 定价页面,核查于 2026 年 9 月。
**最让人意外的成本:**无头浏览器。浏览器会抓取每一张图片、每种字体和每个脚本,因此带宽消耗比纯HTTP请求大约增加一个数量级。如果页面不需要JavaScript,就不要渲染它——如果需要,请屏蔽不需要的资源类型。
如何区分硬阻塞与软阻塞
这种故障模式造成的损失最大,因为它看起来并不像是一种故障。
硬阻塞会返回 403 状态码、挑战页面或连接拒绝。这种故障表现得非常明显,且可立即采取应对措施。
软阻塞则返回 200 状态码,但内容不完整:项目减少、字段被移除、数据过时,或者显示通用页面而非特定页面。您的成功率指标仍保持在 99%,而数据质量却在悄然下降。这正是复杂网站更常见的响应方式,恰恰因为它会在不提供任何提示的情况下消耗您的预算。
请明确防范此类情况:
**验证内容,而非状态码。**检查页面上是否存在已知的稳定标记,若缺失则视为错误。 **验证数量。**如果某个分类页面从未少于二十个项目,则少于二十个即视为失败。 按目标对指标进行分段。 十二个目标的通过率均为 99%,而其中一个仅为 40%,其平均值看起来似乎很健康。 定期与浏览器进行对比。 手动抓取一个页面,并与爬虫获取的内容进行差异比对。
这与我们在为什么测试代理很重要中描述的“静默失败”模式相同,也是“我们被封锁了三周却毫无察觉”成为一种真实事件类别的根本原因。
何时停止
这是代理服务商最不愿撰写的部分。
当条款禁止时。 某些网站会明确规定这一点并严格执行。绕过明确的禁止条款进行技术操作,其后果远不止于技术层面。
当被要求停止时。 来自网站运营商的直接请求即终结了讨论。
当投入超过产出时。 如果你每两周就要重构一次方案,那么获取数据的成本就已超过其价值。这是商业层面的结论,而非技术上的失败。
当存在合法途径时。 例如 API、数据源或授权数据集。支付费用获取正规访问权限,通常比为规避限制而投入的工程时间更划算,而且不会出现故障。
当网站部署了陷阱时。 缓存陷阱和生成式迷宫的设计初衷,就是让你付出的代价高于网站自身——它们提供缓存内容,而你却要按每千兆字节和每计算小时付费。这种不对称性是蓄意的,且无法通过额外努力来克服。
先询问。一封说明您是谁、需要什么以及需求量的邮件,往往比讨论中提到的方法更能解决问题,而且能获得持续有效的访问权限。
大家还常问
为什么我的爬虫总是被封?
通常是速率问题。单个IP地址在短时间内发送过多请求是压倒性多数的常见原因,而这一点完全由您掌控。其余原因主要包括:请求模式不规律、在出现错误时反复重试以及匿名访问。
我能以多快的速度爬取网站?
建议每个域名每1到2秒发起一次请求,只有在确认目标网站能够承受的情况下才可加快速度。如果 robots.txt 设置了速率限制,请遵守 Crawl-delay 的规定。若需要更高的吞吐量,扩大时间窗口比增加并发数更经济且更安全。
使用代理能避免被封锁吗?
仅对基于IP地址的封锁有效。若请求速度过快,即使从更多IP地址发送相同速率的请求,仍会被视为同一速率,从而导致整个IP池被标记。如果您的请求特征被通过TLS指纹或请求头识别出来,这些特征会随您移动,无论使用哪个IP地址。
我应该轮换用户代理吗?
不需要。在单次会话内随机轮换会使客户端看起来像是在访问过程中更换了浏览器,这反而会暴露不一致性,而非起到伪装作用。使用单一真实的用户代理并包含联系 URL,被封锁的概率比任何轮换方案都要低。
收到 429 状态码时该怎么办?
暂停对该域名的请求,并等待的时间至少应达到 Retry-After 指定的时长。如果没有该标头,请从一个宽松的起点开始按指数级降低请求频率,随后再降低稳态速率——这表明你的速率刚刚被判定为过高。切勿立即重试。
如何判断是否被软封锁?
应验证内容而非状态码。检查每页是否存在已知的稳定标记,验证预期项目数量,按目标而非汇总数据划分成功指标,并定期将爬取的页面与浏览器中获取的页面进行对比。
爬取网站是否合法?
这取决于管辖权、网站条款、涉及的数据类型以及你对数据的使用方式。遵守 robots.txt 规定、标识你的爬虫并保持适度的爬取速率是常规做法,但这些都不能凌驾于服务条款或版权之上。对于任何具有商业重要性的行为,请寻求专业建议。
我能做的最有效的一件事是什么?
放慢速度,并确认是否真的需要进行爬取。使用 API、合作伙伴数据源或带有 lastmod 时间戳的站点地图,可以彻底解决问题,而非仅仅缓解问题——而在确实需要爬取的情况下,控制爬取频率比其他所有措施加起来更能防止被封禁。
总结
使这个问题变得可解决的关键在于:阻断是针对负载和不可预测性的响应,而非针对身份。网站并不反对被读取;它们反对的是被某种无法预料且无法联系到的东西疯狂请求。
这使得有效措施的顺序与大多数文章所描述的恰好相反。 首先确认是否真的需要进行爬取,因为 API 或合作伙伴数据源可以彻底解决问题。请阅读 robots.txt 并严格遵守其规范,包括关于特异性匹配以及 5xx 状态码表示停止的部分。控制请求频率并加入随机延迟。通过名称和联系 URL 进行身份识别。积极进行缓存并使用条件请求,确保永远不会重复获取未发生变化的内容。 请遵循 Retry-After 中的指导。
所有这些措施都是免费的,且能避免的封禁比任何基础设施采购都要多。代理服务器仅能解决真正且范围较窄的问题——例如单个 IP 地址的带宽上限,以及因地区而异的内容——除此之外,它们对列表中的其他问题毫无帮助。
同时请牢记上一节的内容。一个已明确条款、部署了拦截措施或要求你停止访问的网站,其实已经向你传达了某种信息;而相比通过技术手段绕过限制,其他替代方案通常成本更低,且始终更具可持续性。
