抓取压力上来的时候,源站最先感受到的是连接数和 CPU。有些站点一遇到蜘蛛密集访问就直接返回 500,或者干脆把连接掐掉。结果往往是:蜘蛛没少来,只是白跑一趟,下一次来得更没规律。
其实 HTTP 状态码本身就是一套跟蜘蛛沟通的语言。用对了,它可以告诉蜘蛛现在别来、或者慢一点;用错了,反而会放大损耗。
先分清几种状态码在说什么
- 200:内容正常。如果返回的是一个系统繁忙提示页,蜘蛛会把它当成正常内容收走,等于把一个无意义页面放进了索引。
- 404 / 410:页面确实不存在。410 比 404 更明确,蜘蛛通常更快把它从待抓队列里划掉。
- 500:服务端内部错误。蜘蛛会认为这是临时故障,过一阵再来,但长期大面积 500 会拖低它对站点的信任度。
- 503:服务暂时不可用。这是最合适的、表达我现在真的扛不住的方式。
- 429:请求太多。偏向于表达你请求频率超了,请放慢。
503 的正确用法:带上 Retry-After
单独返回 503 只说明了不可用,没有说明多久之后可以来。加上 Retry-After 响应头,语义才完整:
HTTP/1.1 503 Service Unavailable,响应头中包含 Retry-After: 3600
这个值可以是秒数,也可以是一个 HTTP 日期,意思是这个时间之后再试。对搜索引擎蜘蛛来说,这比断连和超时友好得多:它至少知道该等多久,而不是靠猜。
有几个边界要注意:
- Retry-After 不要给得过长。几小时量级可以接受,动辄几天容易让蜘蛛把整个站点的抓取频率调低。
- 不要长期全站 503。持续返回 503 的站点,蜘蛛会逐步减少抓取,恢复之后也需要一段时间才把频率加回来。
- 能按路径分就按路径分。评论提交、站内搜索接口、下单流程这些不需要被抓的路径返回 503,正文页面保持 200,比全站一起挡更划算。
429 更适合做细粒度限速
如果说 503 是整体关门,429 更像是你这一路走得太快。按 UA 或按来源 IP 做限速时,超出的请求返回 429,再配上 Retry-After,比直接返回 403 更清楚:403 意味着你没资格,429 意味着稍等再来,后者不会让蜘蛛误判页面的可访问性。
实践中可以这样分层:正常抓取放行,短时间内超过阈值的返回 429 加一个较短的 Retry-After,源站整体压力过大时再切到 503。层次分明,蜘蛛也容易读懂。
和抓取预算的关系
抓取预算不是一份固定配额,蜘蛛会根据抓到的内容有没有价值、站点响应是否稳定来动态调整。一个延迟忽高忽低、时不时冒出 5xx 的站点,即便 URL 数量很多,也很难拿到高频抓取。反过来,响应稳定、状态码语义清晰的站点,蜘蛛更愿意多花时间。
所以限速的目的不是把蜘蛛赶走,而是让每一次抓取都有结果。请求被 503 挡回去,和请求超时被掐断,看起来都是没抓到,但对蜘蛛留下的印象完全不同。
落地时容易踩的几个坑
- 用 200 返回错误页。蜘蛛会当成正常页面反复来抓,白白消耗预算。
- 返回 503 却不给 Retry-After。蜘蛛只能按默认策略重试,节奏未必是你想要的。
- 把 500 当限速手段。500 代表我出故障了,长期使用会拖低整站抓取稳定性的评价。
- 防护规则误伤正常蜘蛛。限速生效后,最好在日志里按 UA 抽样看一遍,确认被拦的是高频异常请求。
- 恢复之后什么都不做。流量回稳后,可以用 Sitemap 或者站内入口重新把重点 URL 推到蜘蛛面前,别指望它立刻自己找上门。
小结
源站能不能稳定响应,是抓取路径里最基础的一环。状态码用对了,等于在蜘蛛和你之间留了一条明确的沟通通道:忙的时候说清楚忙多久,不忙的时候保持干净利落的 200。剩下的 URL 发现和内链结构,才有条件发挥作用。