先给结论:异常恢复后,不要用“抓取请求数回升”或“日志里重新出现某条 URL”直接判定真正修复。更可靠的做法是把样本分成两组——有独立缓存层的 URL 与无缓存层的 URL,分别观察同一路径的响应头、内容指纹和抓取频次是否同步变化;如果只有缓存层那组变化,另一组不变,更可能是缓存过期,而不是源站抓取规则已恢复。
异常恢复初期,最容易踩的坑是只盯一条曾经出问题的 URL。它可能因为缓存刷新而短暂正常,也可能因为抓取调度顺序而延迟变化,两者看起来都像“修复了”。
更稳的做法是选同一目录下、内容结构相近的 URL,分成两组:A 组经过 CDN 或反向代理缓存,B 组直连源站或缓存 TTL 很短。两组都记录同一时间窗口内的响应状态、响应头中的缓存标记、返回内容的关键片段,以及抓取日志里该路径的出现次数。
判断依据不是“有没有恢复”,而是两组是否同步恢复。若 A 组先恢复、B 组仍保持异常,优先怀疑缓存层;若两组在同一时间窗口内一起变化,才更接近源站抓取规则或内容层真正修复。
状态码 200 只能说明这次请求被响应了,不能说明返回的是源站当前内容。异常恢复后,缓存层可能仍保留旧响应,尤其是带较长 max-age 或 s-maxage 的页面。
实施动作:对同一 URL 连续发起两次请求,间隔短于缓存 TTL,比较响应头中的 Age、X-Cache、ETag 或 Last-Modified,以及正文中一段稳定文本的哈希。若两次请求的正文哈希不同,但状态码相同,说明中间存在缓存或版本切换,不能据此认定抓取规则已修复。
结果如何影响下一步:如果内容指纹在短时间内跳变,先清理或绕过缓存再复测;如果指纹稳定但抓取频次仍低,问题更可能在抓取调度、站点地图信号或内部链接,而不是缓存过期。
条件一:站点有独立缓存层,且异常期间缓存未失效。此时优先做缓存旁路验证,例如对同一路径加一个只对内部生效的查询参数或请求头,观察源站返回是否与缓存返回一致。若旁路请求正常、缓存请求仍异常,说明修复尚未穿透缓存,下一步是等待缓存过期或主动刷新,而不是继续改 robots.txt 或站点地图。
条件二:站点无独立缓存层,或缓存 TTL 很短。此时“恢复”更可能来自源站响应变化。应直接比较修复前后的源站响应头、正文和抓取日志时间线。若源站响应已稳定,但抓取频次没有同步回升,不能反推抓取规则未修复;抓取调度本身有延迟,尤其当异常期间大量 URL 被降频时。
两种条件的分界不是“有没有用 CDN”,而是“同一请求是否可能命中与源站不同的副本”。只要存在这个可能,就必须先排除缓存,再谈真正修复。
假设某目录下 20 条 URL 在异常期间返回 503,恢复后其中 12 条变为 200,另外 8 条仍为 503。若这 12 条都位于缓存层之后,而 8 条直连源站,那么更合理的解释是缓存副本先过期,而不是源站抓取规则已全面恢复。
此时动作是:对仍为 503 的 8 条直连 URL 检查源站应用日志和响应头,确认是否仍有上游限流或规则拦截。若源站日志显示这些请求根本没有到达应用层,问题在更前面的网关或抓取规则;若到达了但被应用拒绝,问题在应用层。这个区分会直接决定下一步是调抓取规则、调网关,还是调应用配置。
上述分组法在“个别样本成立、规模化后出现例外”时最需要谨慎。样本量小时,一条 URL 的缓存过期就可能被误判为整体修复;样本量大时,抓取调度、不同机房缓存和内容版本又可能让两组表现交叉。
不能直接照搬的边界包括:robots.txt 的抓取限制不等于可靠的索引移除,站点地图不保证收录,HTTPS 不保证安全无漏洞或排名。这些信号各自解决不同问题,不能因为其中一项变化就推断抓取规则已修复。另外,请求量或抓取量归零也不能单独证明处理正确——它可能是抓取延迟、调度降频或缓存命中导致的,需要结合源站响应和内容指纹一起判断。
真正可操作的收尾动作是:保留一组带缓存的 URL 和一组不带缓存的 URL,在恢复后至少跨一个缓存 TTL 观察它们是否同步稳定;只有两组都稳定,才把这次异常标记为真正修复,否则继续按缓存或源站两个方向分别排查。