入口页为了省带宽,经常会走 CDN 或者开启服务端缓存。这时候搜索蜘蛛来抓取,拿到的可能不是完整的 200 响应,而是 304 Not Modified。不少站长会问:既然页面没有真正传内容,那页面上的目标 URL 还会不会被发现?
304 不等于“没抓”,链接仍来自缓存副本
304 的含义是“你本地那份副本还是最新的,不用重新传了”。搜索蜘蛛收到 304 时,会直接使用自己索引里保存的那份 HTML,然后照常解析里面的链接。也就是说,只要上一次抓取时入口页里已经写了目标 URL,这次链接发现通常依然有效,不会因为 304 而中断。
问题往往出在“上一份副本”上:如果副本是旧的,里面还没有你新加的目标 URL,那这次 304 就等于让搜索蜘蛛继续用旧页面,新链接自然发现不了。
哪些情况会让新加的目标 URL 被缓存挡住
- Last-Modified 或 ETag 设置不对:页面内容改了,但修改时间或内容指纹没变,搜索蜘蛛判断“没变化”,继续使用旧副本。
- CDN 缓存时间过长:入口页更新后,边缘节点还在返回旧内容,搜索蜘蛛拿到的也是这一份。
- 错误版本被缓存:比如把 404、502 或临时跳转的响应缓存下来,并设置了较长的缓存时间。
- 按 UA 区分内容却没设置 Vary:不同 UA 拿到不同版本,缓存可能把几个版本混在一起。
- 入口页是动态生成的列表:每次输出的顺序或分页不同,被缓存住的那一版可能刚好不包含你要的目标 URL。
怎么判断是不是缓存造成的“发现不了”
看日志比猜更可靠。重点看搜索蜘蛛请求入口页时返回的状态码:如果长期只有 304,说明它一直在用缓存副本,这时需要确认这份副本里到底有没有目标 URL。也可以换不同 UA 请求一次入口页,对比返回的 HTML 是否一致;再清掉对应 URL 的 CDN 缓存后重新请求,看内容是否发生变化。
实操上可以这样做
- 入口页内容有增删时,同步更新 Last-Modified,或让 ETag 随内容变化。
- 给入口页单独设置较短的缓存时间,不要和图片、静态资源共用一套长缓存策略。
- 避免把 4xx、5xx 以及临时跳转的响应缓存下来。
- 如果同一个 URL 对不同 UA 返回不同内容,正确设置 Vary: User-Agent。
- 更新入口页后主动刷新缓存,并继续观察一段时间日志里的状态码和实际抓取内容。
两点容易被忽略的细节
一是缓存副本的“年龄”。搜索蜘蛛手里的副本可能来自几天甚至更早,更新入口页后不要指望马上生效。二是多个入口页共用同一套缓存规则时,一处出问题会成片出现同样的现象,排查时按规则分组看,比一个页面一个页面找要快得多。
另外要分清发现和抓取。304 影响的是入口页上的链接能否被解析出来,而目标 URL 最终会不会被继续抓取,还取决于它自身的响应速度、robots 规则以及搜索蜘蛛当次的抓取安排。
304 本身不妨碍链接发现,真正决定结果的是搜索蜘蛛手里那份缓存副本是不是最新的。