常见问题

入口页被 CDN 缓存,改了目标链接后搜索蜘蛛看到的是哪一版

入口页上的目标链接改过了,自己用浏览器看是新版,服务器日志里搜索蜘蛛抓到的却还是旧 HTML。本文说明搜索蜘蛛的请求会经过哪些缓存层、怎样用响应头判断它拿到的是哪一版,以及改完链接后刷新缓存和设置缓存策略的常规做法与几个常见误区。

常见问题

入口页被 CDN 缓存,改了目标链接后搜索蜘蛛看到的是哪一版

在蜘蛛池或普通站点的运营里,经常出现这样的情况:入口页上的目标链接已经改过,自己用浏览器打开也确认是新的,但过一两天去看服务器日志,搜索蜘蛛抓到的还是旧版本 HTML,里面指向的是老 URL。多数时候这不代表蜘蛛「记性差」,而是它拿到的根本就是缓存副本。

搜索蜘蛛请求时,中间隔了哪些缓存层

搜索蜘蛛发起的是一次普通的 HTTP 请求,它经过的链路和你用 curl 请求时基本一致:

  • CDN 边缘节点缓存
  • 反向代理缓存(Nginx proxy_cache、Varnish 等)
  • 应用层页面缓存(部分 CMS、缓存插件生成的静态 HTML)
  • 对象存储或静态托管服务的默认缓存

只要其中一层存着旧副本并且还在有效期内,蜘蛛读到的就是旧 HTML,页面里能被解析出来的目标 URL 自然也是旧的。改文件、清应用缓存,但没清 CDN,是很常见的一种漏项。

蜘蛛本身并不绕过缓存

有一种误解是:搜索蜘蛛是「特殊访客」,缓存对它不生效。实际上蜘蛛只是被动接收响应,它并不会主动跳过 CDN 边缘节点去回源,也不会像浏览器那样读取本地磁盘缓存后再校验。它的行为更接近一个不带 Cookie、不带本地缓存的命令行请求:谁先应答,它就拿到谁给的内容。

唯一需要注意的是,部分 CDN 会按 User-Agent 或 IP 段做分流,例如把已知爬虫直接放行回源,或给爬虫单独一条缓存策略。这会让「浏览器看到旧版、蜘蛛看到新版」或反过来都可能发生,所以最好实测而不是凭经验猜。

怎么确认蜘蛛拿到的是哪一版

  1. 用 curl -I 看响应头,重点看 Age、X-Cache、CF-Cache-Status、X-Cache-Hits 这类字段。Age 值很大,说明命中的是边缘节点上的旧副本。
  2. 连续请求两次,对比两次返回的 HTML 是否完全一致。如果两次都相同却和源站文件不同,基本可以确定中间有缓存。
  3. 把 User-Agent 换成搜索蜘蛛的 UA 再请求一次,观察返回内容或响应头是否变化。
  4. 在服务器日志里对比蜘蛛抓取时返回的字节数,和你当前页面文件大小是否一致,差异明显时通常是缓存或压缩层在起作用。
  5. 如果入口页链接由 JavaScript 注入,抓取工具拿到的 HTML 里本来就不含目标 URL,这时候要先排查渲染问题,而不是缓存问题。

改了链接之后可以做什么

  • 主动刷新缓存。主流 CDN 都提供刷新或预热接口,按 URL 或目录提交即可。刷新是异步的,节点多的时候需要等几分钟到更久。
  • 给 HTML 设置较短的缓存时间。图片、CSS 这类静态资源可以长缓存,但入口页这种链接经常变动的页面,用较短的 max-age,或者用 no-cache 让节点每次回源校验,会更省心。
  • 让缓存键跟着内容变化。改链接时顺带调整路径或查询参数,等于换了一个新缓存键,旧副本自然不会命中。
  • 通过站点地图或提交入口告知更新。这只是一种通知方式,不能替代缓存刷新。
刷新缓存解决的是「蜘蛛看到旧链接」的问题,它不会让蜘蛛立刻回来,也不代表目标 URL 会被收录。抓取和收录是两件互相独立的事。

几个容易踩的坑

第一个坑是只清了一半。源站清了、反向代理清了一部分、CDN 没清,结果蜘蛛抓到的仍是旧版。排查时最好从最外层往里一层层验证响应头。

第二个坑是把刷新缓存当成日常手段,一改链接就全站刷新。频繁刷新会让边缘节点反复回源,源站压力上升,也可能让蜘蛛在短时间内抓到多个版本的同一页面。比较稳妥的做法是把缓存时间设短一点,让版本更替自然发生。

第三个坑是忽略了响应头的隐藏信息。有些托管服务默认给 HTML 加上了较长的 Cache-Control,部署时看不见,出问题时也想不到。上线前用一次 curl 看一眼响应头,比事后翻日志省事得多。

最后,缓存只是影响 URL 发现的一环。蜘蛛能不能发现入口页里的目标链接,还取决于入口页本身是否被抓、页面能否被正常解析、链接是否在可达的 HTML 里。逐项确认比反复改动缓存策略更有效。