蜘蛛池知识

蜘蛛池入口页的 HTTP 响应头:几个容易被忽略的配置细节

入口页能返回 200,不代表配置就没问题。Content-Type、X-Robots-Tag、Server、Location 以及缓存类响应头,往往在排查抓取异常时才会被想起来。本文梳理几类常见响应头的实际影响、容易踩的坑,以及用 curl 和访问日志做检查的基本方法。

蜘蛛池知识

蜘蛛池入口页的 HTTP 响应头:几个容易被忽略的配置细节

很多人排查蜘蛛池入口页的抓取问题时,注意力都放在状态码、页面内容和跳转上,很少去看响应头。实际上,蜘蛛拿到一个 URL 之后,最先解析的就是响应行和响应头,页面正文要等这一步之后才会被处理。响应头里写错了东西,页面本身再正常也可能白搭。

状态码之外,响应头决定了蜘蛛怎么理解这个页面

200 只表示请求成功,它不说明返回的是什么类型的内容、能不能索引、要不要缓存,这些信息都在响应头里。入口页通常是程序批量生成的,如果程序模板里带了某些默认头,几百上千个页面就会一起带上,问题也会被一起放大。

几类值得逐项检查的响应头

Content-Type 与字符集

Content-Type 应该明确写成 text/html 并带上字符集,例如 text/html; charset=utf-8。如果服务器返回 text/plain 或者干脆不写,蜘蛛可能不按 HTML 去解析,页面里的链接也就无法被提取出来。字符集写错则会让中文变成乱码,正文解析出一堆无意义的字符。

X-Robots-Tag

这是放在 HTTP 头里的指令,作用和页面里的 meta robots 类似,但优先级更高。常见的误用是:入口页本身想被蜘蛛抓取,却因为服务器统一加了 X-Robots-Tag: noindex,导致页面抓得到却不会进入索引。

抓取和收录是两件事。noindex 不影响蜘蛛来抓,但会阻止页面进入索引。如果你本来就只希望入口页承担“被爬到、再顺着链接走到目标页”的作用,那么 noindex 本身未必是错,但要清楚自己在做什么,而不是全局一刀切。

Server 与版本信息

Server 头会暴露服务器软件和版本号,比如 nginx/1.18.0。这不是抓取层面的问题,但从运维角度看,公开精确版本号没有什么好处,可以简化成 nginx 一类,或者用配置去掉。顺带检查有没有暴露内部转发信息,比如上游地址、内网 IP。

Location 与跳转

如果入口页需要跳转到目标页,用的是 301 或 302,那么 Location 里的地址必须是完整的绝对 URL,且不能跳到自己、不能形成循环。相对地址、带空格未编码的地址、跳转链条过长,都会让蜘蛛在中间放弃。

缓存与校验类头

Cache-Control、ETag、Last-Modified、Expires 这几项会影响蜘蛛重复访问时的行为。入口页内容长期不变,可以让蜘蛛用 If-Modified-Since 只拿到 304,省下带宽;但如果你希望蜘蛛每次重新解析页面上的链接,缓存时间就不要设得太长。这类设置没有统一答案,取决于入口页是静态展示还是频繁更新。

Content-Length 与实际内容

这个头如果和实际字节数对不上,通常意味着程序在中途出错,或者用了压缩但没有正确处理。蜘蛛可能读到半截内容就断开,表现出来就是抓取不完整、页面大小异常。

几个常见的配置坑

  • 只在部分页面上写了正确的 Content-Type,其余走服务器默认值,而默认值并不是 HTML。
  • 用反向代理或 CDN 回源时把源站头部改写掉,或者叠加出两个 Content-Type。
  • 为了防采集加了一堆自定义头,其中某个与蜘蛛的解析逻辑冲突。
  • 跳转配置写在应用层,但响应头里的 Location 指向了测试环境地址。
  • 页面引用了 http 资源,却没有意识到混合内容对抓取和渲染的影响。

怎么查:curl 加日志两步

最直接的方式是用 curl 看响应头,把 UA 换成你关心的爬虫,多测几个不同路径的入口页,看看头部是否一致。如果服务器对爬虫和普通用户返回不同的头,这一步就能看出来。

第二步是看访问日志。日志里记录的状态码、返回字节数和响应时间,可以和 curl 的结果互相印证。如果某个入口页在日志里反复出现 200 但字节数为 0 或极小,多半不是内容问题,而是响应头或程序输出有问题。

小结

响应头不需要天天盯,但在入口页上线之前、以及抓取表现异常的时候,值得花十几分钟逐项过一遍。它属于那种平时不出声、出问题很难查的配置,提前把模板规范好,比事后一个个补要省事得多。