页面内容本身没问题,抓取却总是不顺,问题有时出在看不见的地方——HTTP 响应头。响应头是服务器给爬虫和浏览器的第一层说明,状态码只是其中一行,字符集、缓存校验、抓取指令同样写在这里。它不占页面体积,却直接影响抓取方如何理解一条 URL。下面按几类常见头部逐项梳理。
一、X-Robots-Tag:最容易误伤的抓取指令
X-Robots-Tag 的作用和页面里的 meta robots 类似,但写在响应头中,对图片、PDF、JS 等无法写 meta 的资源尤其有用。风险也在这里:它作用范围往往由服务器或 CDN 配置统一决定,一旦写错,影响的是整批 URL 而不是单个页面。
- 只想着屏蔽测试环境或后台目录,规则却匹配到了正式栏目;
- 临时加了 noindex 做排查,事后忘记移除;
- CDN、反向代理或安全防护层附加了指令,源站配置里看不到;
- 对整站统一加了 noindex,只在少数路径上做了例外。
建议把站内所有 X-Robots-Tag 配置集中记录一份,注明添加时间、适用范围和负责人。对重要栏目页、内容页,抽查确认头部里没有 noindex、none 之类的指令。
二、Content-Type 与字符集
Content-Type 应完整包含类型与字符集,例如 text/html; charset=utf-8。如果只写 text/html 而页面又依赖 meta 声明编码,解析环节多一层判断,遇到编码不一致时容易出现乱码,影响正文识别。常见的坑是把 sitemap.xml、robots.txt 返回成 text/html,或把 JSON 接口返回成 text/plain,虽然未必立刻出错,但会增加解析歧义。
三、Last-Modified 与 ETag
这两个头部用于判断资源是否发生变化。Last-Modified 缺失时,抓取方难以知道页面何时更新;时间被统一写成服务器当前时间,则每次访问都像刚改过,反而失去参考价值。ETag 如果由多台机器各自生成,同一页面可能返回不同的值,容易出现无意义的重复拉取。内容更新后,这两个值应当跟着变化;内容没变,则保持一致。
四、Vary 与缓存相关头部
Vary 用来告诉缓存:同一 URL 在不同请求头下可能返回不同内容。对按设备、语言或登录状态返回不同 HTML 的站点,缺少正确的 Vary 会让缓存把某一版本发给所有访问者,抓取到的内容与预期不符。同时留意 Cache-Control 的取值,过长的缓存时间会让更新后的内容延迟生效,过短则增加回源压力。
五、一条可以直接执行的自查清单
- 列出站内所有会写入响应头的环节:源站、反向代理、CDN、安全防护。
- 抽查首页、主要栏目页、内容页、图片与 PDF 各若干条,确认没有意外的不索引指令。
- 确认 HTML 返回的 Content-Type 带正确字符集。
- 确认动态页面有合理的 Last-Modified 或 ETag,且更新后数值会变。
- 确认需要区分版本的页面配置了 Vary。
- 把以上配置写进改版与上线流程,避免只在出问题时临时排查。
六、怎么快速检查
命令行下用 curl -I 加上目标地址,即可只取响应头,不必下载正文;对比不同路径的返回结果,差异通常一眼可见。浏览器开发者工具的 Network 面板也能看到同样的信息,适合核对单页。若站点走 CDN,建议分别请求源站与 CDN 地址,确认两处头部一致。
响应头的调整往往牵一发动全身,改动前先记录原始配置,改完后用同一批 URL 复检一遍,比事后凭印象回溯要可靠得多。
响应头不会让内容变好,但它决定了内容能不能被正确读到。把这项检查纳入日常巡检,付出的时间不多,却能挡掉不少莫名其妙的抓取问题。