蜘蛛不是只来一次。一个 URL 被发现后,会在一段时间内被反复访问。但反复访问不等于反复完整下载。很多搜索引擎蜘蛛在第二次、第三次访问时,会先发一个条件请求,询问服务器内容有没有变化。理解这段交互,能减少不必要的传输,也能避免让蜘蛛误判页面更新频率。
条件请求是怎么发出来的
当蜘蛛第一次抓取某个 URL 时,服务器通常在响应头里带上 Last-Modified 或 ETag。下次蜘蛛再访问同一个 URL 时,请求头里就可能出现:
- If-Modified-Since:对应 Last-Modified,告诉服务器“我上次抓到的时间是这个”。
- If-None-Match:对应 ETag,告诉服务器“我上次拿到的标识是这个”。
服务器收到后,可以判断内容是否变化。如果没变,返回 304 Not Modified,正文不传输;如果变了,返回 200 和新的正文。
304 对蜘蛛意味着什么
304 不是“不抓取”,而是一次有效的访问记录。蜘蛛确认 URL 可访问、状态正常,但不需要重新下载和解析正文。对站点来说,这能减少带宽和服务器压力;对蜘蛛来说,也能把省下的传输时间用在其他 URL 上。
把 304 当成“拒绝抓取”是一种误解。它只是告诉蜘蛛:内容没变,不用再传一遍。
配置时容易踩的坑
Last-Modified 不稳定
有些程序在每次请求时动态生成 Last-Modified,或者时区处理不对,导致每次返回的时间都不一样。蜘蛛会以为页面一直在更新,于是反复完整抓取,反而增加消耗。
ETag 每次都变
部分框架会用文件 inode、进程 ID 或随机值拼 ETag。同一份内容在不同请求里得到不同 ETag,条件请求就永远对不上,304 也就无法生效。
CDN 与源站响应头不一致
如果源站返回了稳定的 ETag,但 CDN 层又覆盖或剥离了相关头,蜘蛛在不同时间可能看到不同版本。需要确认最终到达客户端的响应头是否稳定。
和抓取预算的关系
304 能节省传输,但不会凭空增加蜘蛛的抓取配额。蜘蛛仍然要为这次访问排队、建连、等待响应。真正影响抓取量的,还是 URL 发现是否充分、站点响应是否稳定、抓取路径是否清晰。条件请求更像是锦上添花:让重复访问更轻,而不是让蜘蛛来得更勤。
一个简单的检查清单
- 用 curl -I 连续请求同一个 URL,观察 Last-Modified 和 ETag 是否稳定。
- 在日志里统计 304 的比例。如果长期为零,可以检查是否响应头配错或被中间层改掉。
- 确认 404、410 等失效页面不要返回 304,避免蜘蛛误以为它们仍然有效。
- 对需要实时更新的页面,不要强行长期返回 304;对稳定页面,则适合让缓存头正常工作。
条件请求不是抓取优化的核心,但它属于服务器与蜘蛛之间最基础的对话。把响应头配稳,蜘蛛重复来访时就能少下载、少折腾,站点也能把资源留给更需要的请求。