入口页一旦被搜索蜘蛛抓过几次,服务器往往会开始收到带条件的请求,返回 304 Not Modified。这时日志里看不到 200,也看不到完整 HTML,很多做蜘蛛池的人就会担心:既然没返回正文,页面里的目标链接是不是也没被读到?
先说结论:304 本身不是问题,缓存对不上才是
304 的含义是“内容没变,用你上次那份”。搜索蜘蛛在抓取过一个 URL 之后,本地会保留一份快照和链接关系。再次抓取时它会带上 If-Modified-Since 或 If-None-Match,服务器确认内容未变就回 304,蜘蛛直接用本地缓存版本继续处理。
所以,只要首次抓取是正常的 200,且页面里当时就有那些目标链接,后续的 304 一般不会让链接凭空消失。真正容易出问题的是另一种情况:页面明明改了,服务器却回了 304。
304 是怎么产生的
- 服务器根据 Last-Modified 判断:请求头里的时间不早于文件修改时间,就回 304。
- 服务器根据 ETag 判断:请求头里的 ETag 与当前一致,就回 304。
- 中间的 CDN、反向代理、Nginx 缓存层自己做了判断,直接把缓存的 304 或 200 吐出来,源站甚至没收到请求。
这三种情况里,前两种通常是准确的;第三种最容易出现“源站内容变了,蜘蛛拿到的还是旧版本”的偏差。
哪些写法会让新增的目标链接被延后发现
1. 内容变了但 ETag、Last-Modified 没变
有些程序会给入口页写死一个固定的 Last-Modified,或者 ETag 只按 URL 生成、不按内容生成。结果就是你在页面里新增了一批目标链接,蜘蛛下次来还是拿到 304,缓存版本里自然没有新链接。这种延迟可能持续到缓存过期或被强制刷新为止。
2. CDN 把入口页当成长期静态资源缓存
入口页本质是动态列表页,如果被 Cache-Control 设成很长的 max-age,或者被 CDN 的“全部缓存”规则命中,蜘蛛拿到的就是旧快照。新增链接、删除链接都不会及时体现。
3. 不同 UA 命中不同缓存
有些配置按 User-Agent 分缓存,但没有正确设置 Vary,导致搜索蜘蛛拿到的是给普通用户看的版本,或者反过来拿到一个空壳版本。表现上看是 200,实际正文里没有目标链接。
4. 首抓失败后又一直回 304
如果第一次抓取时页面超时、返回 5xx,蜘蛛没有建立有效快照,后续服务器再回 304,它手上没有可用版本,这次抓取基本等于作废。所以入口页的稳定性比“省不省流量”重要得多。
自查清单
- 翻日志,看入口页的状态码分布:200 与 304 各占多少,是否出现异常比例的 304。
- 连续两次手动请求同一个入口页,对比 Last-Modified、ETag 是否随内容更新而变化。
- 在入口页新增一条测试链接,然后不带条件请求一次,确认返回 200 且 HTML 里能看到新链接。
- 检查 CDN 与反代规则,确认入口页没有被长期强缓存,或者缓存时间在可接受范围内。
- 确认没有把搜索蜘蛛的 UA 单独导向一个内容不同的版本。
比较稳妥的做法
- 入口页不做过度缓存,缓存时间控制在几分钟到十几分钟量级,内容更新能较快反映。
- 让 Last-Modified 和 ETag 真实反映内容变化,不要写死。
- 新增或删除目标链接时,确保页面 HTML 有实际变化,这样条件请求自然会返回 200。
- 入口页保持轻量、可稳定访问,避免首抓就失败。
需要提醒的是,304 只影响“这次抓取要不要重新传正文”,它不决定目标 URL 最终会不会被索引。搜索蜘蛛是否顺着链接继续访问、目标页是否被收录,还取决于目标页本身能否正常打开、内容是否有价值。入口页能做的是把发现这一步做顺,后面的结果不是它能单方面决定的。