日志只说明蜘蛛来过,不说明它拿到了什么
服务器日志能记录访问时间、状态码和 User-Agent,但它看不到蜘蛛实际收到的响应体。有些情况在日志里是一行漂亮的 200,实际返回的却是风控拦截页、空壳 HTML,或者一段被替换过的内容。想确认蜘蛛看到了什么,最直接的方式是用命令行完整复现一次抓取。
复现之前先准备三样东西:一个你关心的 URL、日志里出现过的蜘蛛 UA,以及这个域名当前解析到的地址。
第一步:确认请求发到了哪里
命令行发请求和浏览器一样走本地网络,但这不代表请求一定落到了你预期的机器上。CDN 边缘节点、负载均衡后的某一台后端,返回结果可能并不相同。
- 先看域名解析结果,确认是否经过 CDN;
- 需要直连源站时,用 curl --resolve 域名:443:源站IP 把请求钉到指定地址;
- 同时带上 Host 头,避免虚拟主机返回默认站点。
这一步的意义是排除“测的其实是另一台机器”这种最常见的误判。
第二步:用蜘蛛的身份发请求
把 User-Agent 换成日志里出现的值,完整拷过来,包括版本号和括号里的信息。很多站点、风控和 CDN 会按 UA 分流,用默认的 curl UA 去测,等于测了一个并不存在的场景。
想看重定向的完整链条,加上 -L;只想看响应头,加 -I 或用 -s -o /dev/null -D -;想同时拿到状态码、耗时和最终地址,可以用 -w 输出这几项。
第三步:逐项读响应头
响应头是排查抓取问题时信息密度最高的地方,重点看这几项:
- 状态码:200 之外,301/302 是否指向最终地址,403 是否来自风控,5xx 是否偶发;
- Content-Type:是不是 text/html,有没有把页面当成下载文件返回;
- Content-Encoding:gzip 或 br 是否声明正确,声明了却没压缩会白白消耗抓取时间;
- Location:跳转链有几跳,是否出现循环;
- Cache-Control 与 Vary:缓存版本是否随 UA 变化,移动版和桌面版会不会互相覆盖;
- X-Robots-Tag:是否在响应头层面禁止索引,这个字段经常被忽略。
第四步:看响应体里真正有什么
响应头看完,再确认内容本身。可以把响应体存成文件,用编辑器打开对照页面源码。
- 首屏正文是否出现在 HTML 里,还是完全依赖 JS 渲染;
- 主要导航和内容链接是否是真的 a 标签,而不是点击事件;
- 字符集是否正确,中文有没有出现乱码;
- 页面里有没有被插入风控脚本、跳转脚本或与主题无关的内容。
第五步:换几个身份再比一次
同一条 URL,在不同条件下可能是三份不同的内容。建议至少对比以下几组:
- 移动 UA 与桌面 UA,看链接和正文是否有差异;
- 带 UA 与不带 UA,看是否直接返回 403;
- 登录态与未登录态,看是否被要求跳转;
- 有条件的话换一个出口地区,看 CDN 缓存是否造成版本差异。
差异本身不一定是问题,真正的问题是你不清楚蜘蛛拿到的是哪一份。
把结果固定成一张检查表
单次复现只能回答当下的疑问。更实用的做法是把上面几步固化成一张表:URL、复现时间、UA、状态码、最终地址、Content-Type、正文是否可读、链接是否可读,各自写上结论。
这张表在几个时间点特别有用:站点改版后、上线新的 CDN 或风控规则后、发现抓取量异常下降后。同一张表前后对比,比对着日志反复猜要快得多。
命令行复现只能回答“蜘蛛能不能拿到这一份内容”。拿不到,说明链路确实有问题;拿到了,也不代表一定会被收录。它的价值在于把不确定的猜测,换成可以复现的事实。