搜索抓取

蜘蛛再次抓取同一页时:304、Last-Modified 与 ETag 在做什么

蜘蛛抓过的页面,第二次来时往往不会重新下载整份内容,而是先带上验证头发问:内容变了吗?服务器用 Last-Modified、ETag 和 304 来回答。理解这条往返链路,能减少无效传输,让抓取时间花在真正更新过的页面上。

搜索抓取

蜘蛛再次抓取同一页时:304、Last-Modified 与 ETag 在做什么

蜘蛛抓一个页面,并不是每次都从头到尾把内容重新下载一遍。对已经抓过的 URL,它更常见的做法是先带上几个验证头,问服务器一句:这份内容还是我上次拿到的版本吗?服务器回答“是”,流程就到此为止;回答“不是”,才重新传一遍。这条往返链路就是条件请求,也是抓取效率里常被忽略的一环。

第一次抓取留下的两样东西

第一次抓取时,服务器通常会在响应头里给出两个标识:Last-Modified 和 ETag。前者是内容最后修改的时间,精度到秒;后者是服务器生成的一串字符,代表这个版本的指纹。蜘蛛会把这两样东西随 URL 一起记下来,下次再抓这个地址时,把它们分别放进 If-Modified-Since 和 If-None-Match 请求头里带回来。

304 是怎么发生的

  1. 蜘蛛请求 /page-a,并带上 If-None-Match: "abc123"。
  2. 服务器比对当前内容的 ETag,如果仍是 "abc123",直接返回 304 Not Modified,不带正文。
  3. 蜘蛛确认页面没变,沿用上次解析出的内容与链接,不再重复解析。
  4. 如果 ETag 变了,服务器返回 200 和新正文,蜘蛛按新内容处理。

整个过程省下的是正文传输和后续解析。对体量大的站点,这部分节省并不小;对蜘蛛来说,它可以用同样的时间确认更多 URL 的状态。

Last-Modified 与 ETag 各管什么

两者不是二选一的关系。Last-Modified 更接近“内容什么时候动过”,方便蜘蛛判断页面的更新节奏;ETag 更接近“内容是不是同一个版本”,对动态生成的页面更可靠。有些服务器只给其中一个,蜘蛛也能工作,但两个都给,判断会更准。

容易被忽略的几种配置

  • ETag 每次都变:部分框架会把进程 ID、时间戳塞进 ETag,导致同一个页面每次响应的指纹都不同。蜘蛛每次都收到 200 和完整正文,条件请求形同虚设。
  • Last-Modified 长期不动:页面内容其实更新了,但时间戳停留在建站那天。蜘蛛可能因此降低回访频率,新内容迟迟等不到确认。
  • 把 304 当成缓存专属:304 是给所有支持条件请求的客户端用的,蜘蛛同样会发这些头,不需要特殊配置,也不能靠它去“引导”蜘蛛。
  • Cache-Control 与抓取混为一谈:CDN 缓存时间长短影响的是回源次数,和蜘蛛是否重新抓取并不等价。两者都需要,但解决的是不同问题。

对站点运营意味着什么

条件请求的价值主要在两头。一头是服务器:大量 304 响应比大量 200 响应轻得多,抓取高峰时压力更可控。另一头是蜘蛛:它花更少时间在没变化的页面上,就有余力去看看新发布或刚改过的 URL。

如果站点每天的更新集中在少数栏目,可以观察这些栏目的 Last-Modified 是否正常推进。更新了却不动,往往说明是模板或发布时间字段的问题,不是蜘蛛的问题。

需要说明的是,304 只影响蜘蛛是否需要重新获取内容,不代表它会因此加快抓取,也不构成任何收录上的保证。它更像是把一次抓取的成本压低,让有限的时间用在更有价值的地方。真正决定抓取结果的,仍然是内容本身、站点结构和可访问性。

实践上可以这样自查:用一个正常的 HTTP 客户端模拟带 If-None-Match 的请求,看服务器是否正确返回 304;再对比页面实际更新时间和响应头里的时间戳是否一致。这两步做过之后,再去看日志里的抓取频次,判断会更清楚。