常见问题

入口页返回 304 或命中缓存,搜索蜘蛛还会解析里面的目标链接吗?

搜索蜘蛛抓取入口页时,服务器返回 304 或命中缓存是很常见的情况。很多人担心页面没有返回正文,里面的目标链接就不会被读到。本文拆解 304 的产生条件、搜索蜘蛛如何使用缓存版本,以及哪些配置会让新增链接被延后发现,并给出一份可执行的自查清单。

常见问题

入口页返回 304 或命中缓存,搜索蜘蛛还会解析里面的目标链接吗?

入口页一旦被搜索蜘蛛抓过几次,服务器往往会开始收到带条件的请求,返回 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,它手上没有可用版本,这次抓取基本等于作废。所以入口页的稳定性比“省不省流量”重要得多。

自查清单

  1. 翻日志,看入口页的状态码分布:200 与 304 各占多少,是否出现异常比例的 304。
  2. 连续两次手动请求同一个入口页,对比 Last-Modified、ETag 是否随内容更新而变化。
  3. 在入口页新增一条测试链接,然后不带条件请求一次,确认返回 200 且 HTML 里能看到新链接。
  4. 检查 CDN 与反代规则,确认入口页没有被长期强缓存,或者缓存时间在可接受范围内。
  5. 确认没有把搜索蜘蛛的 UA 单独导向一个内容不同的版本。

比较稳妥的做法

  • 入口页不做过度缓存,缓存时间控制在几分钟到十几分钟量级,内容更新能较快反映。
  • 让 Last-Modified 和 ETag 真实反映内容变化,不要写死。
  • 新增或删除目标链接时,确保页面 HTML 有实际变化,这样条件请求自然会返回 200。
  • 入口页保持轻量、可稳定访问,避免首抓就失败。
需要提醒的是,304 只影响“这次抓取要不要重新传正文”,它不决定目标 URL 最终会不会被索引。搜索蜘蛛是否顺着链接继续访问、目标页是否被收录,还取决于目标页本身能否正常打开、内容是否有价值。入口页能做的是把发现这一步做顺,后面的结果不是它能单方面决定的。