搜索抓取

429 与 Retry-After:给蜘蛛限速时该怎么回应

服务器扛不住蜘蛛抓取时,直接把超出的请求一律拒掉并不是好办法。本文说明 429、503、403 的语义差别,Retry-After 该怎么写,长期限速会给抓取节奏带来什么影响,以及怎样分目录限速、先减负再限速,并用访问日志确认限速没有误伤正文页的抓取。

搜索抓取

429 与 Retry-After:给蜘蛛限速时该怎么回应

站点被蜘蛛抓得太猛、服务器扛不住时,很多人的第一反应是在网关加一条规则,把超出阈值的请求一律拒掉。结果是蜘蛛收到的既不是“稍后再来”,也不是“页面没了”,而是一个模糊的错误。这里只说一件事:当你确实需要给蜘蛛限速时,怎么回应才不至于让它误判站点状态。

先分清 429、503 和 403

三个状态码在日志里都像“拒绝”,但对蜘蛛的含义完全不同。

  • 429 Too Many Requests:请求数量超了,服务器本身是好的。语义是“你现在太快,等会儿再来”。
  • 503 Service Unavailable:服务暂时不可用,通常是维护或过载。蜘蛛一般会放缓节奏并稍后重试。
  • 403 Forbidden:明确不允许访问。用错地方,等于告诉蜘蛛这个 URL 以后别再来了。

把 429 和 403 混用是常见问题:前者是节奏问题,后者是权限问题,蜘蛛的处理方式差别很大。

Retry-After 是给蜘蛛的计时器

429 和 503 都可以带上 Retry-After 响应头,值可以是秒数,也可以是 HTTP 日期。写了这个头,蜘蛛至少有明确的重试时间参考;不写,它只能按自己的退避经验去猜。

如果只是短时限速,给一个具体秒数通常比留空更有帮助,比如 60 或 300。

但不要给出过长的值。写成 86400,含义接近“一天别来”,实际效果是把相关目录往后推,和主动降低抓取频次没多大区别。

长期返回 429 会怎样

蜘蛛会记录站点的响应历史。如果某个目录长期返回 429,它通常会降低该目录的抓取频次,把配额挪去别处。这个过程是渐进的,不会立刻停抓,但恢复起来也不快。

所以限速尽量做成分目录、分类型的:慢接口、站内搜索、导出接口单独限速,正文页保持正常。全站一刀切,最后被压住的往往是真正需要被抓的页面。

几个常见的误用

  • 把 429 当成反爬的万能开关,正常蜘蛛被挡住,自动化脚本照样跑。
  • 依赖 robots.txt 里的 Crawl-delay 限速,主流蜘蛛并不严格遵循,写了只是心里安慰。
  • 限速只加在 CDN 边缘,回源依然被压垮,问题只是往后推了一环。
  • 接口本身慢导致的超时,用 429 掩盖过去,蜘蛛看到的是限速,不是你真实的故障。

比限速更划算的是先减负

在动手写限速规则之前,先看响应时间分布:是数据库查询慢,还是模板渲染慢,还是同一时刻并发太高。加一层页面缓存、给列表页做静态化、把重查询的接口挪到独立服务,这些改动通常比限速规则更能提升整体抓取量。

怎么确认限速没有伤到抓取

在访问日志里按状态码和 UA 统计一段时间的分布,重点看两件事:

  1. 429 占该蜘蛛请求量的比例,是否长期高于一个很小的水平。
  2. 被限速的 URL 之后有没有重新被抓,间隔是否在拉长。

如果某个目录的 429 比例一直很高,而且后续重试越来越少,说明限速范围开得太大,应该收窄到具体的慢路径上。

限速是手段而不是目的。让蜘蛛慢一点可以接受,让它误以为站点坏了或者页面消失了,代价要大得多。