搜索抓取

缓存层与抓取:蜘蛛拿到的页面是哪个版本

蜘蛛抓取的页面往往不是源站直接返回的版本,而是经过 CDN 或反向代理缓存后的副本。本文梳理命中缓存、回源失败、缓存键按 UA 分叉、错误页被缓存等情况对抓取的影响,并给出用蜘蛛视角自查与更新后主动刷新缓存的实用做法。

搜索抓取

缓存层与抓取:蜘蛛拿到的页面是哪个版本

排查抓取问题时,很多人只盯着源站:状态码对不对、HTML 有没有坏、内链通不通。但从蜘蛛发出请求到拿到 HTML,中间还隔着缓存与 CDN。这一层如果配置不一致,蜘蛛看到的页面可能和用户看到的不同,甚至和它上一次抓到的完全一样。

蜘蛛的请求先落在哪一层

常见链路是:蜘蛛 → DNS → CDN 边缘节点 → 源站。如果边缘节点上有可用副本,请求不会再回到源站。这意味着源站日志里根本不会出现这次抓取,而蜘蛛拿到的可能是几小时甚至几天前的版本。只看源站日志做抓取分析,很容易漏掉这一部分访问。

命中与回源的区别

  • 命中缓存:响应快,源站没有日志,返回内容取决于副本年龄,响应头里的 Age 可以反映这一点。
  • 回源:源站产生日志,返回当前版本,但延迟更高、资源消耗更大。
  • 回源失败:可能返回 5xx,也可能被缓存下来,在一段时间内持续影响抓取。

几类容易踩到的不一致

缓存时间设得过长

HTML 文档如果被设置了很长的 s-maxage 或 max-age,内容更新后边缘节点仍返回旧版。蜘蛛再访时看到的内容没变化,自然不会判断为更新过的页面。动态页面通常更适合短缓存加回源校验,长缓存留给长期不变的资源。

缓存键把蜘蛛和用户分开了

有些配置会按 User-Agent、Cookie 或设备类型区分缓存。如果蜘蛛的 UA 命中了另一份副本,你看到的页面和它看到的可能不是同一份。响应里的 Vary 头能反映这类分歧,排查时要留意。缓存键分得越细,副本越多,不一致的概率也越高。

回源错误被当成正常内容缓存

源站短暂 5xx 或超时,如果缓存规则把错误响应也存了下来,蜘蛛接下来一段时间会持续拿到错误结果。表现为源站已经恢复,抓取却仍然失败。这类问题往往要等缓存过期才自行消失。

JS、CSS 被缓存层额外拦截

部分站点在 CDN 上对静态资源和脚本做了额外限制,蜘蛛拿不到完整的渲染资源,看到的页面结构与实际不符。这类情况常常表现为抓取正常,但内容不完整。

用蜘蛛的视角做一次自查

  1. 用蜘蛛的 User-Agent 请求关键 URL,对比与浏览器请求返回的 HTML 是否一致。
  2. 查看响应头中的 Age、Cache-Control、X-Cache、CF-Cache-Status 等字段,确认是命中还是回源。
  3. 把源站日志和 CDN 日志对一遍,找出只有 CDN 有记录、源站没有的抓取请求。
  4. 对同一 URL 连续请求两次,观察第二次是否返回同一份副本,判断缓存颗粒度。
  5. 在内容更新后立刻用蜘蛛 UA 请求一次,确认拿到的是新版本而不是旧副本。

缓存层与抓取稳定性的关系

缓存命中率下降时,回源请求会成倍增加,源站压力上升,超时和 5xx 的概率也随之变大。蜘蛛遇到连续的失败响应会放慢节奏,短时间内就不再频繁回访。所以缓存配置不只是性能话题,它间接决定了服务器能不能稳住抓取流量。

内容更新之后可以做的事

  • 更新重要页面后,主动刷新对应 URL 的缓存,而不是等 TTL 自然到期。
  • 给 HTML 设置较短的缓存时间,把长缓存留给图片、字体这类不常变的资源。
  • 缓存键尽量简单,避免按 UA 分叉出多份 HTML 副本。
  • 让回源错误不进入缓存,或者把错误响应的缓存时间设得极短。
  • 服务器压力大的时候观察回源比例,命中率下降往往先于抓取异常出现。
缓存不是抓取优化的技巧,而是抓取链路上的一环。它决定了蜘蛛实际拿到什么,而不是你希望它拿到什么。

蜘蛛看到的页面是整条链路末端的结果,源站只是其中一段。把 CDN、反向代理和源站三处的返回版本对一遍,很多“抓取正常但内容不对”的问题会变得容易解释,也更容易定位到具体该改哪一层。