蜘蛛池知识

蜘蛛池入口页的响应头:Last-Modified、ETag 与 Cache-Control 如何影响蜘蛛回访

蜘蛛每次抓取都会读响应头,Last-Modified、ETag 与 Cache-Control 决定了它下次要不要来、来的时候看到的是哪一份内容。本文讲清三者各自的作用、常见的错误写法,以及如何用访问日志和回源请求验证头部是否按预期工作。

蜘蛛池知识

蜘蛛池入口页的响应头:Last-Modified、ETag 与 Cache-Control 如何影响蜘蛛回访

蜘蛛回访时,先读的是响应头

很多站点运营者把注意力放在页面内容和链接上,却忽略了服务器返回的响应头。蜘蛛每次抓取一个 URL,除了拿到 HTML,还会读一组头部字段,其中 Last-ModifiedETagCache-Control 直接影响它下一次要不要来、来的时候拿的是不是同一份内容。对蜘蛛池的入口页来说,这种影响会被放大:入口页数量多、更新频率不一,头部写错很容易造成要么反复抓取、要么长期不抓。

Last-Modified:最直观的“上次改动时间”

它的作用是告诉蜘蛛这个页面最后一次变化的时间。蜘蛛再次访问时可能带上 If-Modified-Since 请求头,如果服务器判断内容没变,返回 304,蜘蛛就不必重新下载整页。这能省下抓取预算,对入口页数量多的站点是件好事。

容易写错的地方

  • 把 Last-Modified 写成当前时间。每次请求都返回“刚刚修改”,蜘蛛会认为页面一直在变。
  • 批量生成的入口页共用同一个时间戳,等于告诉蜘蛛这批页面是同一次改动的,缺乏区分度。
  • 页面内容更新了,头部时间没跟着变,蜘蛛可能几周都不来取新版。

ETag:更细,也更容易被误用

ETag 相当于内容指纹,蜘蛛用 If-None-Match 与它比对。问题在于:如果 ETag 是每次请求随机生成(比如按进程 ID、请求时间拼接),那么同一份内容每次返回的 ETag 都不一样,蜘蛛会判断内容每次都变,结果就是反复抓取一个根本没变的页面。

ETag 的原则很简单:内容不变,值就不变;内容一变,值就必须变。做不到这一点,不如干脆不返回。

有些服务器会根据文件 inode 或部署时间生成 ETag,每次发布、扩容、换机器都会变,同样会造成无谓的回访。

Cache-Control:蜘蛛不一定听,中间层一定听

搜索引擎爬虫通常有自己的抓取节奏,不一定会严格按 Cache-Control 决定是否重抓。但 CDN、反向代理、负载均衡会严格遵守。也就是说,蜘蛛看到的是中间层给它的那一份。如果 CDN 缓存了一份旧的空白页,或者缓存了 404 响应,蜘蛛拿到的东西和你在源站看到的完全不同。

常见的情况是:入口页上线后改了内容,源站已经更新,CDN 还在返回几天前的版本,蜘蛛连续几次抓到的都是旧内容,于是降低了回访频率。

三者怎么配合

  • 内容型入口页:给出真实的 Last-Modified,ETag 保持稳定,Cache-Control 设置合理的 max-age,让 CDN 承担大部分请求。
  • 频繁更新的入口页:max-age 不要太长,避免蜘蛛长期看到旧版本。
  • 已下线页面:返回 410 或 301,并让中间层不要继续缓存旧的 200 响应。
  • 批量模板页:确认每个 URL 的头部是可预期的,不要出现随机 ETag。

用日志做核对

  1. 看蜘蛛请求里是否出现了 If-Modified-Since 或 If-None-Match,说明缓存协商在正常工作。
  2. 统计 304 的比例。比例过低,可能是 Last-Modified 或 ETag 一直在变。
  3. 同一个 URL 连续抓取多次,对比返回的 ETag 是否一致。
  4. 换一个网络位置请求,或直接回源,确认 CDN 返回的头部与源站一致。

几个常见误区

  • 以为把 max-age 设得很长就能让蜘蛛少来,实际上它只影响中间层,不影响蜘蛛自身的抓取策略。
  • 以为 ETag 有没有都无所谓,随机 ETag 会造成明显的重复抓取。
  • 只检查首页的响应头,忽略了入口页、过渡页可能由不同规则生成。
  • 换了服务器或 CDN 之后没有重新核对头部,行为悄悄发生改变却没人察觉。

小结

响应头不是装饰。Last-Modified 说的是“什么时候变的”,ETag 说的是“变成了什么样”,Cache-Control 决定中间层能替源站回答多久。把这三件事对齐,蜘蛛拿到的版本才更接近你希望它看到的那一份,回访节奏也更符合预期。检查频率不必很高,但每次上线、换机器、调 CDN 之后,都值得花几分钟确认一下。