搜索抓取

服务器回 304 之后,蜘蛛这一趟抓到了什么

蜘蛛再次抓取同一个 URL 时,请求头里常带着条件请求标记,服务器如果回 304,这一趟就不会传正文。本文说明 304 的判断依据、动态页面与 CDN 常见的实现偏差,以及怎么用条件请求和日志验证自己的配置是否准确。

搜索抓取

服务器回 304 之后,蜘蛛这一趟抓到了什么

蜘蛛再次访问一个已经抓过的 URL 时,请求头里常常会带上 If-Modified-Since 或 If-None-Match。这两个头的意思很直白:上次我拿到的是这个版本,如果现在还一样,就告诉我一声,不用把整页传回来。服务器判断内容没变,就会回 304 Not Modified。

304 是抓取过程中很常见的一种响应,但它经常被误读。它不是“蜘蛛没来”,也不是“蜘蛛放弃了这个页面”,只是这一趟没有传输正文。它节省的是传输和解析的消耗,页面在爬虫侧依然是被看过的。

304 发生在哪一步

一次典型的重复抓取大致是这样:

  1. 蜘蛛请求 URL,带上上次记录的修改时间或 ETag。
  2. 服务器拿当前内容去比对这两个值。
  3. 一致就返回 304,响应体为空;不一致就返回 200,重新传一遍完整页面。

所以 304 只代表“和上次相比没变化”,并不能说明页面质量、排名或者抓取频次有什么结论。

正确实现 304 需要什么

要让 304 判断准确,前提是服务器能分清“变了”和“没变”。常见做法有两种:

  • Last-Modified / If-Modified-Since:基于最后修改时间。静态页面、图片、CSS 这类直接映射到文件的资源比较容易做准。
  • ETag / If-None-Match:基于内容生成的标识,通常更精确,但要求同一份内容稳定生成同一个 ETag。

麻烦多半出在动态页面上。如果模板里嵌了当前时间、随机数、会话 ID,或者每次都算出不一样的 ETag,蜘蛛每次都会拿到 200,条件请求形同虚设。反过来,如果内容已经改了,但程序逻辑没有更新 Last-Modified,服务器仍然会回 304,蜘蛛就继续拿着旧版本。

304 的前提是服务器说真话。判断逻辑一旦有偏差,省下的那点带宽换来的可能是蜘蛛长期看不到更新。

几个容易被忽略的地方

反向代理与 CDN 这一层

如果 CDN 或反向代理缓存了 ETag,而源站内容已经更新,缓存层可能仍按旧标识回 304。排查这类问题,要分别看源站直连和经过 CDN 的响应头是否一致,单看一侧容易得出错误结论。

304 和抓取频率没有直接关系

有些运营者想通过频繁返回 304 来“减少蜘蛛访问”。实际效果有限,因为蜘蛛是否再来、间隔多长,取决于站点整体更新情况、链接变化、抓取预算等多个因素。把 304 当成频率开关,通常达不到预期。

空响应不代表可以忽略状态码

304 的响应体是空的。如果日志里只统计字节数或内容长度,很容易把这类请求当成异常。统计时应单独看状态码分布,区分 200、304、301、404 各自的比例。

怎么验证自己站点的 304 是否正确

  1. 用命令行工具带条件头请求页面:先记下一次响应里的 Last-Modified 或 ETag,再用它发起第二次请求,看是否返回 304。
  2. 改动页面内容后重复上述请求,确认返回的是 200 而不是 304。
  3. 在服务器日志里按状态码聚合,看静态资源和 HTML 的 304 比例是否合理。
  4. 对经过 CDN 的 URL,在源站和 CDN 侧各做一次对比。

小结

304 是抓取过程中的一个效率细节。做对了能减少无谓传输,做错了可能让蜘蛛长期停留在旧版本上。它替代不了内容更新、内链调整和 Sitemap 维护,但当你在排查“蜘蛛为什么没看到新内容”时,它是一个值得优先检查的具体项。