入口页的正文、URL 结构、链接拓扑经常被反复讨论,但响应头这类“看不见的配置”往往没人细看。对蜘蛛来说,响应头是它判断这份内容能不能用、要不要缓存、下次什么时候再来的第一批信号。写错一个字段,通常不会立刻出问题,却会让抓取效率慢慢变差。
一、响应头为什么值得单独拿出来看
蜘蛛请求一个 URL 时,最先拿到的是状态行和响应头,之后才是正文。它从中读出几件事:这份内容是什么类型、有多大、能不能缓存、有没有额外的抓取指令。正文写得再好,如果头部把内容类型标错,或者给蜘蛛返回了“别抓”的信号,前面做的工作就白费了。
二、Cache-Control:别把蜘蛛也一起缓存住
Cache-Control 原本是给浏览器和 CDN 用的,但蜘蛛也会参考它来决定自己的抓取节奏。常见问题有这几类:
- max-age 设得过长:比如一年。页面更新了,缓存层和蜘蛛都可能继续拿旧版本。
- 把入口页设成 no-store:虽然能保证每次都是新的,但会额外增加回源压力,对入口页这种需要反复抓取的页面并不划算。
- CDN 与源站头不一致:源站设了短缓存,CDN 规则又覆盖成长期缓存,实际给蜘蛛的是后者。
比较稳妥的做法是:入口页按实际更新频率给一个合理的 max-age(几分钟到几小时),并配合 ETag 或 Last-Modified 让缓存可以校验,而不是每次都完整回源。
三、Vary:写错会让缓存命中率掉下去
Vary 告诉缓存“这个响应会因为哪些请求头而不同”。常见误用是把 Vary 写成 Vary: *,意思是任何请求头不同都算不同资源,缓存基本失效,每次请求都回源。入口页被高频访问时,这会直接体现为源站压力上升。
如果站点确实按 Accept-Encoding 之类的字段区分内容,Vary 里只写真正用到的字段即可。另外要留意一种隐性风险:有些站点会给不同 User-Agent 返回不同内容,这本身就容易让蜘蛛和普通访客看到不一致的页面。与其靠 Vary 掩盖,不如先确认这种区分是否真的有必要。
四、X-Robots-Tag:方便,也容易误伤
X-Robots-Tag 可以在 HTTP 头里下发抓取指令,作用范围比 meta robots 更广,能覆盖图片、PDF 等非 HTML 资源。但它有两个坑:
- 写在全局配置里:服务器或 CDN 的默认头一旦带上 noindex,整个域名的页面都可能收到这个信号,而排查时很少有人第一时间想到去看响应头。
- 和正文里的 meta 冲突:两处指令不一致时,更严格的那个通常生效,结果往往不是你以为的那个。
建议把 X-Robots-Tag 的使用范围收窄到明确的目录或文件类型,改动前先在一两个 URL 上验证,不要直接在全局层动手。
五、几个顺手一起检查的头
- Content-Type:声明与实际内容要一致,charset 也要写对,否则容易出现解析偏差。
- ETag / Last-Modified:给缓存和蜘蛛一个校验依据,能减少重复传输。
- Retry-After:返回 503 时配合这个头,比让蜘蛛反复重试更友好。
- Content-Length:与实际传输量不符时,部分客户端会截断或等待超时。
六、一份可以照着核对的清单
- 用命令行工具拉一次入口页的完整响应头,再和 CDN 回源时看到的做对比。
- 确认 Cache-Control 的 max-age 与页面实际更新频率匹配。
- 检查 Vary 是否被写成了通配符。
- 全局搜索 X-Robots-Tag 的配置位置,确认没有意外的 noindex。
- 确认内容类型、字符集、ETag 都正常。
- 改动后隔一段时间看日志,观察抓取状态和返回码有没有变化。
响应头的问题通常不会立刻显现,它更像是慢慢拖低效率的因素。与其一次性大改,不如把它纳入常规巡检,每次只动一个变量,便于回看效果。
把响应头当成入口页配置的一部分来维护,并不需要多复杂,但要保证源站、CDN 和蜘蛛看到的是同一套东西。这种一致性带来的确定性,往往比多堆几个入口页更有价值。