改版那两周 AI 爬虫没再来过:503、Retry-After 与维护窗口的 GEO 规范解读

2026-09-29 01:28:27 0 次浏览
GEOAI爬虫Retry-AfterHTTP 503抓取治理Nginx

官网改版切流量那天,我们把整站挂到统一维护页上,Nginx 直接吐 503,忘了带 Retry-After。两周后恢复上线,百度和 Google 的收录一周内就缓了过来,日志里 GPTBot 的日均抓取却从 1400 多次掉到不足 200 次,爬了快一个月才回到原来的水位。传统搜索引擎恢复得快,AI 爬虫恢复得慢,差距就出在 503 后面缺的那一行响应头。

适用读者:负责企业官网运维的后端与运维工程师;正在做生成式引擎优化(Generative Engine Optimization, GEO)、关心「AI 搜索引擎怎么读我的站」的内容负责人;近期要给官网安排一次大改版、正在评估维护窗口方案的技术决策者。

先把现场摆出来

这次改版是官网四年一次的大重构:域名没动,URL 结构微调,前端框架整体更换。为了不让用户看到半成品页面,我们决定在切换期间整站返回维护页。

网站维护窗口与爬虫等待的主题图

操作上很直接:Nginx 层加一个开关,命中后统一返回超文本传输协议(HyperText Transfer Protocol, HTTP)503 状态码,配一张「系统升级中」的静态页。当时的配置里只写了 error_page 503 /maintenance.html,没有加 Retry-After 响应头——这是我后来复盘时反复后悔的一处遗漏。

恢复上线后,我们按周统计了几家爬虫的日均抓取次数,数据是这样的:

爬虫 改版前基线 恢复第 1 周 第 2 周 第 3 周 第 4 周
GPTBot 1420 186 342 780 1290
ClaudeBot 610 90 175 410 590
PerplexityBot 530 210 390 480 520
Googlebot 8600 5100 7400 8800 8900

两组对比很有意思。Googlebot 在第 3 周就基本回到基线;GPTBot 和 ClaudeBot 走了一条很陡的恢复曲线,到第 4 周还在爬坡;PerplexityBot 反而几乎没受影响,第 1 周就恢复到四成。后续排查结论是:PerplexityBot 对 Retry-After 的依赖弱,而前两家对「站点声明了多久恢复」这个信号非常敏感——我们恰恰没给这个信号。

机制剖析:503 和 429 在 HTTP 语义里不是一回事

这里值得把机制讲透。HTTP 规范(RFC 9110)里,503 Service Unavailable 表示服务端暂时不可用,是临时状态,并明确建议服务端在响应里带上 Retry-After 头,告诉客户端「多久之后可以再来」。而 429 Too Many Requests 的语义是「请求太多,是客户端的问题」,属于限流场景。

对爬虫调度器来说,这两个码会走进完全不同的分支:

  • 收到 503 + Retry-After:调度器把「指定时间后再来」写进调度队列,抓取预算(crawl budget)不被扣减或只轻微扣减。
  • 收到裸 503:调度器只能按内置的指数退避策略处理,重试间隔翻倍往上走。改版两周的窗口里,退避间隔会从几分钟一路涨到按天计。
  • 收到 404 或 410:语义是「资源没了」,部分调度器会直接把抓取频率砍到最低档,甚至触发索引摘除。
sequenceDiagram
    participant B as AI 爬虫
    participant S as 官网 Nginx
    B->>S: GET /product/a100
    S-->>B: 503 + Retry-After: 3600
    Note over B: 调度器记录:3600 秒后回访<br/>抓取预算不变
    B->>S: 1 小时后再次 GET
    S-->>B: 200 OK
    Note over B: 正常抓取,关系不受损
    B->>S: 若上次只有裸 503
    S-->>B: 503(无 Retry-After)
    Note over B: 指数退避:5 分钟 → 30 分钟 → 6 小时 → 24 小时

所以维护窗口期的正确姿势不是「返回 503 就完事」,而是返回带明确恢复预期的 503。Retry-After 的值可以是秒数,也可以是 HTTP 日期,秒数对调度器更友好。窗口预估 6 小时就写 21600,写不准则宁可写短一些,让爬虫多空跑几趟,也别写长了把回访周期拉爆。

三家 AI 爬虫对 Retry-After 的尊重程度

这是我们观察最久、也最值得记录的部分。三家主流 AI 爬虫对 503 的处理差异不小,把我们四周日志里能看到的规律整理成表:

爬虫 对 Retry-After 的态度 维护期典型表现 恢复后行为
GPTBot 明确尊重,按头里的时间回访 有头时频次稳定,无头时快速退避到天级 回访后一周内爬回八成水位
ClaudeBot 尊重但保守,恢复曲线偏缓 无头时退避更快,第 1 周几乎不抓 恢复偏慢,第 3 周才明显回升
PerplexityBot 依赖较弱,自行试探 维护期间仍持续低频探测 一恢复就抓,对 503 不记仇
Googlebot(对照) 尊重并按规范处理 降频但不撤索引 恢复最快,约 1 周回基线

从 GEO 的视角看,这个差异有实际后果:如果你的目标受众常通过 AI 搜索获取答案,ClaudeBot 和 GPTBot 这类「记性」较好的爬虫在维护期被冷落后,恢复期内容进不了 AI 答案的引用池,短则两周、长则一个月。AI 搜索场景里,站点可用性信号本身就是优化手段,不只是运维指标。

维护窗口:503、临时下线还是 shouldBlock

改版期间的可选方案不止一种,各方案的语义和代价差别很大:

方案 HTTP 语义 对抓取/索引的影响 适用场景
503 + Retry-After 暂时不可用,稍后重试 降频不撤页,恢复最快 小时级到 3 天内的窗口
404 / 410 资源不存在 可能触发索引摘除 基本不适用于维护
200 + 维护页 一切正常 维护页被当正文收录,恢复后污染 不推荐
robots.txt 全站 Disallow 不许抓(Robots Exclusion Protocol, RFC 9309) 被当作内容下架处理,恢复后需重新发现 仅长期关闭站点
DNS 摘除 / 整站下线 连接层不可达 调度器无从判断原因,退避最狠 极端情况兜底

很多团队习惯在改版前往 robots 协议文件里加一条全站 Disallow,俗称 shouldBlock,认为这是「最干净的暂停」。实际效果恰恰相反:robots.txt 的语义是「永不来抓」,不是「暂停几天」。搜索引擎对全站 Disallow 的解读接近「站长主动撤下了内容」,恢复后要经历完整的重新发现和评估流程,比 503 慢得多。

我们的结论是一句话版的:窗口在 72 小时内,用 503 + Retry-After;窗口更长,别硬扛 503,改走静态快照或灰度上线,让站点大部分时间以正常状态可达。

把决策过程画成图,改版排期会上直接照着走就行:

flowchart LR
    A[准备进入维护窗口] --> B{预估窗口时长}
    B -->|72 小时以内| C[503 + Retry-After]
    B -->|超过 72 小时| D[静态快照 / 灰度上线]
    C --> E[开关文件 touch 即生效]
    D --> F[保持大部分页面 200 可达]
    E --> G[恢复日:删开关 + curl 自测 200 + 提交 sitemap]
    F --> G
    G --> H[盯日志看爬虫回访曲线]

Nginx 维护窗口配置怎么写

下面是这次改版后我们沉淀下来的 Nginx 配置,经过了两个维护窗口的验证:

# 环境依赖:Nginx 1.20+,标准编译即可,无需第三方模块
# 用法:维护开始时 touch /etc/nginx/maintenance.on,结束即删,无需 reload

server {
    listen 443 ssl;
    server_name www.example.com;

    # 维护开关:开关文件存在即认为整站进入维护窗口
    # 运维只需 touch 或 rm 这个文件,避免改配置引 reload 风险
    set $maintenance 0;
    if (-f /etc/nginx/maintenance.on) {
        set $maintenance 1;
    }

    # 命中维护窗口:统一返回 503,不要 404 也不要 200 加维护页
    # 503 在 RFC 9110 里明确表示「服务暂时不可用,稍后重试」
    if ($maintenance = 1) {
        return 503;
    }

    # 503 的统一出口:返回静态维护页
    # Retry-After 必须挂在 503 响应上,always 保证错误响应也带头
    error_page 503 /maintenance.html;
    location = /maintenance.html {
        root /var/www/maintenance;
        # 21600 即 6 小时:改版窗口按小时估,别写 86400 这种天级值
        add_header Retry-After 21600 always;
        # 明确声明内容类型,避免部分解析器把维护页当正文缓存
        add_header Content-Type "text/html; charset=utf-8";
        # 禁止索引维护页本身,防止升级文案混进搜索结果
        add_header X-Robots-Tag "noindex" always;
    }
}

三个关键行再强调一下。add_header Retry-After ... always 里的 always 不能漏,没有它错误响应不会带头;Retry-After 的值按窗口时长估算并留余量;X-Robots-Tag: noindex 负责保护维护页自身不被收录,它和 Retry-After 各管一件事,缺一不可。

恢复后怎么把抓取频次拉回来

恢复上线当天有四件事要做,顺序别乱。先 curl -I 自测首页和几个核心栏目页,确认状态码回到 200、维护开关文件已删干净;再确认 sitemap 时间戳已更新,主动给搜索引擎提交一轮;然后保持 ETag 和 Last-Modified 正常工作,让回访爬虫能用条件请求省流量;最后就是盯日志,每天看一眼爬虫回访量。

日志统计用一条 awk 就够,不用上重型工具:

# 环境依赖:任意 Linux shell + awk,Nginx 默认 combined 日志格式
# 用途:按天统计三家 AI 爬虫的抓取次数,观察恢复曲线

# 先按引号切段取出 UA 字段,匹配到具体爬虫再按日期分组计数
awk -v FS='"' '
  $6 ~ /GPTBot/       { bot="GPTBot" }
  $6 ~ /ClaudeBot/    { bot="ClaudeBot" }
  $6 ~ /PerplexityBot/{ bot="PerplexityBot" }
  # 有匹配才输出,避免普通用户请求混进统计
  bot != "" { print substr($4, 2, 11), bot; bot="" }
' access.log | sort | uniq -c | sort -k2

我们按这个流程走完后,第 5 周 GPTBot 日均抓取回到 1360 次,达到基线的 96% 左右;ClaudeBot 回到 580 次。对照当时「以为恢复上线就万事大吉」的预期,这一个月的爬坡期完全是可以压缩的——如果维护期一开始就带上 Retry-After,GEO 内容进 AI 答案引用池的空窗估计能缩短一半以上。

几个容易踩的误区

第一是返回 200 加一张好看的维护页。看起来对用户友好,实际上爬虫会把「系统升级中」当正文抓走,AI 引擎引用你官网时可能引到这句升级文案,清理成本远高于多写一行响应头。

第二是 Retry-After 写得过于保守。86400(一天)这种值会让爬虫认为明天再来了,多天窗口直接把回访周期拉到天级。宁可写短让爬虫多空跑,也别写长。

第三是维护期顺手改 URL 结构。站点不可达期间,爬虫无法跟随 301 更新旧地址的索引状态,改版恢复后会同时面对「抓取频次低」和「路径变了」两个问题叠加,恢复期翻倍。这类结构迁移应该放在站点正常可达的窗口单独做。

趋势层面说一句:AI 搜索引擎对站点可用性信号的敏感度只会越来越高,因为生成式答案对引用来源的时效要求比传统搜索更苛刻。维护窗口的 HTTP 语义处理,正在从运维细节变成 GEO 的基本功。

参考与延伸

  • RFC 9110(HTTP 语义,503 与 Retry-After 的规范定义):https://www.rfc-editor.org/rfc/rfc9110.html
  • RFC 9309(Robots Exclusion Protocol,robots.txt 的正式规范):https://www.rfc-editor.org/rfc/rfc9309.html
  • MDN Retry-After 响应头文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Retry-After

改版窗口期的 HTTP 语义并不复杂,一个 503 加一行 Retry-After 就能把恢复期从一个月压到两周以内,剩下的差别只是配置里有没有认真写那一行。如果你也在改版后遇到过爬虫抓取断崖,欢迎评论区贴一下你的恢复曲线,看看不同引擎的退避策略还有哪些差异。

关键词:GEO、AI 爬虫、Retry-After、HTTP 503、抓取频次、维护窗口、爬虫协议

🤖
本内容由 AI 辅助生成,经人工校对审核;部分素材、资料来源于公开网络,仅作个人观点分享与交流使用,无任何商业侵权意图。若内容、图片、文字涉及您的合法著作权、版权权益,请联系本人,核实后将第一时间删除、修改相关内容。