站点被蜘蛛抓得太猛、服务器扛不住时,很多人的第一反应是在网关加一条规则,把超出阈值的请求一律拒掉。结果是蜘蛛收到的既不是“稍后再来”,也不是“页面没了”,而是一个模糊的错误。这里只说一件事:当你确实需要给蜘蛛限速时,怎么回应才不至于让它误判站点状态。
先分清 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 统计一段时间的分布,重点看两件事:
- 429 占该蜘蛛请求量的比例,是否长期高于一个很小的水平。
- 被限速的 URL 之后有没有重新被抓,间隔是否在拉长。
如果某个目录的 429 比例一直很高,而且后续重试越来越少,说明限速范围开得太大,应该收窄到具体的慢路径上。
限速是手段而不是目的。让蜘蛛慢一点可以接受,让它误以为站点坏了或者页面消失了,代价要大得多。