搜索抓取

重访时的 304:条件请求与缓存头怎么影响蜘蛛判断

蜘蛛重访页面时并不总是重新下载整份 HTML,而是带上条件请求头。服务器返回 304 表示内容未变。本文说明 Last-Modified 与 ETag 的作用、凭证不稳定的几种常见情况、如何在访问日志里核对 304,以及它和 Sitemap lastmod 之间的关系。

搜索抓取

重访时的 304:条件请求与缓存头怎么影响蜘蛛判断

蜘蛛第一次抓完页面后,后续重访并不总是重新下载整份 HTML。如果服务器支持条件请求,蜘蛛会带上 If-Modified-Since 或 If-None-Match,服务器判断内容没变就回一个 304,告诉对方内容还是原来那份。理解这套机制,能解释很多日志里看起来奇怪的现象。

条件请求的两种凭证

Last-Modified 与 If-Modified-Since 用时间做比较,粒度到秒;ETag 与 If-None-Match 用内容标识做比较,粒度更细。两者可以同时存在,服务器按自己的规则决定用哪个。对抓取来说,关键不是用哪一种,而是这个值要稳定:内容没变时,凭证也不能变。

常见的凭证不稳定

  • ETag 由进程 ID、时间戳或随机数生成,每次请求都不同,蜘蛛每次都被判定为新内容。
  • Last-Modified 取自动态生成时间,页面内容没变但时间一直在跳。
  • 反向代理或 CDN 改写了响应头,回源与边缘的 ETag 不一致。
  • WAF 拦掉了 If-None-Match 请求头,服务器每次都返回 200 加完整正文。

这几种情况不会直接导致抓取失败,但会让蜘蛛做很多无效下载,占用抓取额度,也可能让它误判页面的更新频率。

日志里怎么确认

在访问日志中按状态码统计即可:304 的数量、对应的 URL,以及同一 URL 上 200 与 304 的交替情况。

  1. 挑一批内容基本不变的页面,看它们重访时是否稳定返回 304。
  2. 如果全是 200,先看响应头里的 ETag 是否每次都变,再看中间层有没有改写。
  3. 如果 304 比例异常高但页面其实已经改过,检查缓存层是否给出了过期的凭证。
304 表示内容没变,不表示没被抓。它同样是蜘蛛的一次有效访问,只是没有传输正文。

和 Sitemap 的 lastmod 配合

Sitemap 里的 lastmod 是给蜘蛛的另一种提示,和 HTTP 层的凭证本质上是同一件事的两种表达。如果 lastmod 写着昨天更新,而服务器对同一 URL 一直回 304,两个信号就互相矛盾。更新内容后,让 lastmod、Last-Modified、ETag 三者一起变化,是最省事的做法。

几个值得注意的细节

  • 304 不传输正文,蜘蛛拿到的是它缓存里的副本。如果副本已经过期而服务器仍回 304,更新可能被延迟感知。
  • 对频繁变动的页面,比如列表页和首页,缓存头不宜设置过长,否则蜘蛛看到的一直是旧版本。
  • 对稳定不变的内容页,允许 304 是好事,既省带宽,也能让蜘蛛把额度留给别的 URL。
  • 服务器不稳定时,条件请求可能返回 5xx 或超时,这时要按服务器问题排查,而不是当成缓存配置问题。

小结

把 304 理解成一次确认而不是一次抓取失败,排查思路就清晰了:先确认凭证是否稳定,再确认中间层有没有改写响应头,最后看 Sitemap 的 lastmod 和 HTTP 层是否说了同一件事。三处对齐,蜘蛛对页面更新状态的判断才不会来回摇摆。