入口页更新了目标链接之后,如果抓取日志里搜索蜘蛛的访问记录看起来“毫无变化”,很多人的第一反应是蜘蛛没来抓。但更常见的情况是:它来了,也确实读了页面,只是拿到的 HTML 不是你以为的最新版本——中间隔了一层 CDN 或反向代理缓存。
搜索蜘蛛和浏览器请求的不是同一份内容
你在浏览器里打开入口页,请求可能带 cookie、走回源、命中本地或私有缓存;搜索蜘蛛请求时通常不带 cookie,走的是 CDN 边缘节点,命中的是面向所有访客的公开缓存版本。如果缓存键不区分这些差异,边缘节点很可能把很久以前的 HTML 直接返回。
缓存本身没有错。问题在于入口页的链接属于“会变的内容”,而缓存策略常常是按“不会变”来配置的,两者一旦错位,就会出现“源站已改、蜘蛛仍读旧版”的现象。
怎么确认拿到的是旧版本
用命令行直接看响应头
用 curl -I 带上搜索蜘蛛的 UA 请求入口页,重点看 Cache-Control、Age、X-Cache、CF-Cache-Status 这类头。Age 数值很大,基本说明命中了较老的缓存。再用 curl 拉一次完整正文,和源站当前生成的内容做对比。
对比抓取日志里的响应大小
如果日志记录了响应字节数,把最近几次抓取的字节数和当前页面实际大小对一下。如果差别明显且长期稳定,而不是随机波动,那大概率就是缓存层返回了固定旧版本。
用抓取测试工具看实际 HTML
部分站长工具会展示蜘蛛实际拿到的 HTML。注意看里面有没有新加的链接、旧链接是不是还在。看清楚“蜘蛛看到什么”,比盯着访问次数更有意义。
常见的缓存配置误区
- Cache-Control 里的 s-maxage 设得很长,边缘节点几天都不回源;
- 缓存键没有把查询串或 UA 纳入,动态参数被整体忽略;
- 源站更新后没有主动刷新缓存,只是等自然过期;
- CDN 面板里另有一层页面规则,覆盖了源站返回的缓存头;
- 入口页本由程序动态生成,却被当成静态资源长时间缓存。
这里要提醒一点:不建议专门针对搜索蜘蛛的 UA 单独返回不同内容,那属于 cloaking 的方向,风险远大于收益。正确的目标应该是对所有访客都返回同一份最新内容,而不是给蜘蛛开小灶。
更新入口页链接时的稳妥顺序
- 先改源站,确认直接访问源站时已经是新版本;
- 主动刷新 CDN 缓存,或者把入口页的缓存时间设置得短一些;
- 入口页这类索引型页面可以配较短的 s-maxage,配合 stale-while-revalidate 使用;
- 刷新之后,用带蜘蛛 UA 的请求复查一次,确认拿到的是新 HTML;
- 再观察几天的抓取日志,看蜘蛛是否读到了新链接。
别把缓存问题和抓取频率低混在一起
如果蜘蛛本来就很少来,那首先要解决的是入口页的可抓取性和更新节奏,缓存只是其中一环。两者的表面现象很像——旧链接一直在被访问——但处理方向不同:一个是内容分发问题,一个是抓取调度问题。先判断属于哪一类,再动手改配置,能少走不少弯路。
缓存旧版本还有一个副作用:你明明已经删掉的旧链接仍然被抓,日志里 404 数量上升,容易让人误以为站点出了新问题。排查时先确认“蜘蛛读到的到底是哪一版页面”,很多疑问会立刻清晰。
缓存解决的是“蜘蛛看到什么”,不解决“蜘蛛来不来”。把这两层拆开看,排查效率会高很多。