搜索抓取

蜘蛛拿到的那份页面:CDN 缓存、Vary 头与多版本内容

缓存能让蜘蛛抓得更快,也可能让它一直看到旧内容。本文梳理 Vary 头、移动版分组、地域节点与 Cookie 造成的多版本差异,并给出用响应头、回源对比和日志自查的方法,帮你确认蜘蛛实际拿到的是哪一份 HTML。

搜索抓取

蜘蛛拿到的那份页面:CDN 缓存、Vary 头与多版本内容

很多人把抓取异常归到服务器性能上,却忽略了一层:蜘蛛请求某个 URL 时,回给它的往往不是源站刚刚生成的那份 HTML,而是 CDN 或反向代理缓存里的一个副本。缓存配置不同,蜘蛛看到的内容就可能和用户、和你在浏览器里看到的完全不一样。

蜘蛛拿到的是哪一个版本

缓存本身不是坏事。命中缓存意味着响应更快、源站压力更小,对高频抓取的站点通常是加分项。问题在于缓存键怎么定义:如果只按 URL 缓存,所有请求方共享一份;如果按 URL 加某些请求头缓存,就会出现多份并存的版本,而蜘蛛只拿到其中一份。

Vary 头决定分不分叉

当响应里带 Vary: User-Agent 或 Vary: Accept-Encoding 这类头时,缓存会按对应请求头存多个副本。用户代理不同、压缩方式不同,都会各存一份。蜘蛛的 UA 往往落在某个不太常见的分组里,如果这个版本的缓存长期没有被刷新,蜘蛛可能反复拿到一份旧内容,而源站早就更新了。

移动版与桌面版的分组

同一个 URL 按设备返回不同 HTML 的站点,要特别留意缓存分组是否覆盖了蜘蛛的 UA。有些配置里只有常见浏览器 UA 才命中「正常」那份缓存,蜘蛛命中的是兜底版本,内容缺字段、缺内链,抓取路径自然就断了。

地域节点之间不一致

多节点 CDN 下,各边缘节点的缓存状态是各自演进的。蜘蛛从不同出口 IP 过来,拿到的可能是不同节点上的不同版本。排查时如果只在一台机器上测试,很容易得出「内容没问题」的结论。

Cookie、同意弹窗与登录态

另一类分叉来自请求方身份。带 Cookie 的请求通常绕过公共缓存直接回源,不带 Cookie 的请求走缓存。蜘蛛一般不携带你的会话 Cookie,所以它看到的是访客版本——如果访客版本被同意弹窗、地域提示遮住正文,或者被重定向到别的地址,抓取到的有效内容就很少。

  • 同意弹窗由前端脚本注入时,检查未执行脚本的 HTML 里还剩多少正文;
  • 登录墙、付费墙后面是重要内容时,确认蜘蛛能拿到的那一版是否至少包含标题、摘要和可用链接;
  • 用 Cookie 做 A/B 测试的站点,注意别把蜘蛛卷进实验分组。

自查可以从这几个地方入手

  1. 用蜘蛛的 UA 请求一次 URL,观察响应头里的缓存状态字段,看清楚是命中、回源还是已过期;
  2. 把「走缓存」和「直接回源」两次返回的 HTML 并排对比,看正文与内链是否一致;
  3. 查服务器日志里同一 URL 的返回字节数,如果长期固定不变而页面早已改版,多半是缓存在供旧版本;
  4. 检查缓存过期时间,静态资源可以设长,HTML 不宜过长。

缓存策略与抓取稳定性之间

缓存的目标是让响应更快更稳,而不是让蜘蛛一直看旧页面。对 HTML 这类会变的资源,宁可短缓存加回源校验,也别设成一个季度不动。

还有一点常被忽略:缓存层返回 5xx 时,蜘蛛收到的是错误信号,可能触发降低抓取频次。源站偶尔抖动被缓存放大成持续错误,恢复时间会比想象中长。

抓取这件事,很多时候不是蜘蛛没来,而是它来了、也拿到了响应,只是那份响应和你以为的不一样。把缓存的版本差异理清楚,URL 发现和内链路径才有稳定的起点。