很多人在蜘蛛池入口页上启用了缓存,本意是降低服务器压力、加快响应。但过一段时间发现:入口页里明明新增了目标 URL,搜索蜘蛛也来过,却没有去抓这些新链接。这时很容易怀疑“蜘蛛是不是被 304 挡住了”。要回答这个问题,先要理解搜索蜘蛛抓取入口页时,缓存是怎么参与判断的。
搜索蜘蛛遇到 304 时,会发生什么
搜索蜘蛛第一次抓取入口页时,服务器一般返回 200,并带上 ETag 或 Last-Modified。蜘蛛会把页面内容和这些标识一起存下来。下一次再抓同一个 URL 时,蜘蛛通常会带上 If-None-Match 或 If-Modified-Since 请求头,问服务器“内容变了没有”。
如果服务器认为没有变化,就返回 304 Not Modified,不带响应体。蜘蛛收到 304 后,会沿用本地缓存版本,通常不会重新下载和解析页面。也就是说,304 本身不是错误,它节省了带宽和抓取预算,但如果入口页的链接已经更新,而服务器仍然返回 304,蜘蛛就可能继续用旧版本,看不到新链接。
哪些缓存设置容易让新链接“迟到”
Cache-Control 的 max-age 太长
入口页如果设置了很长的 max-age,中间层和蜘蛛都可能认为页面长期有效。若你依赖页面 HTML 里的链接发现目标 URL,建议对入口页使用较短的缓存时间,或设置 no-cache 但允许 304 校验。这样蜘蛛每次来都能确认页面是否变化。
ETag 生成方式不稳定或过于稳定
有些服务器用文件修改时间、inode 或动态内容生成 ETag,页面内容变了但 ETag 不变,蜘蛛就会收到 304;反过来,ETag 每次请求都变,蜘蛛又会反复下载完整页面。比较稳妥的做法是让 ETag 与入口页的链接内容相关,内容变化时 ETag 跟着变。
Last-Modified 没有随链接更新
如果入口页是动态生成,但 Last-Modified 一直沿用旧值,蜘蛛会认为页面没更新。动态入口页可以考虑不发送 Last-Modified,只靠 ETag 或 Cache-Control 控制,避免给出错误的“未修改”信号。
CDN 或反向代理缓存未刷新
入口页套了 CDN 后,蜘蛛访问到的是 CDN 节点。若 CDN 缓存了旧 HTML,即使源站已经更新,蜘蛛拿到的仍是旧版本。需要确认 CDN 的缓存规则、刷新机制,以及回源时是否按正确的主机头和后端路径取内容。
怎么排查入口页 304 是否影响新链接发现
- 用 curl -I 或浏览器开发者工具查看入口页响应头,确认是否返回 304,以及 Cache-Control、ETag、Last-Modified 的值。
- 在入口页新增一条明显的测试链接,再请求一次,看响应头里的 ETag 或 Last-Modified 是否变化。
- 检查 CDN 和反向代理的缓存命中情况,必要时手动刷新入口页 URL。
- 在服务器日志中观察入口页的 304 比例。如果长期大量 304,同时新链接迟迟不被抓,就需要调整缓存策略。
- 新增目标 URL 后,配合 sitemap 更新、主动提交或页面内容变更,让蜘蛛有理由重新抓取入口页。
304 不是敌人,关键是“内容变化要能被发现”
对搜索蜘蛛来说,304 可以节省抓取资源,本身不是坏事。真正要避免的是:入口页已经新增了链接,但服务器、CDN 或缓存层仍然告诉蜘蛛“没变化”。只要你让入口页在链接更新时产生可识别的变化,并给蜘蛛留出重新抓取的路径,304 就不会成为 URL 发现的障碍。
如果你的蜘蛛池入口页更新频繁,建议把缓存校验做好:内容变,标识变;内容不变,再返回 304。这样既省资源,也不耽误搜索蜘蛛发现新目标 URL。