先给结论:静态响应与脚本渲染结果不同,通常不是 robots.txt 本身“变了”,而是两者读取的对象不同。静态响应读的是服务器直接返回的文本,脚本渲染读的是执行 JavaScript 或经中间层处理后的结果。定位差异要从请求路径、响应内容和解析主体三处分开比对,而不是只看最后哪边显示“允许”或“禁止”。
最常见的矛盾是:浏览器打开 /robots.txt 看到一份内容,脚本请求同一路径却拿到另一份内容。两者可能都“正确”,只是命中了不同缓存、不同主机或不同协议版本。
可核对的证据包括:
如果静态请求命中 CDN 边缘缓存,而脚本请求带上了不同查询串或请求头,绕过缓存拿到源站版本,差异就出现了。此时下一步不是改规则,而是先固定请求条件,让两边访问同一缓存层级。
当静态响应与脚本渲染结果不一致,第一种成立条件是:源站返回了不同内容,但缓存或分发层让其中一方看到了旧版本。
区分它的证据是缓存命中状态和回源记录。假设源站刚更新 robots.txt,把某个目录从禁止改为允许,但 CDN 仍缓存旧文件。静态请求可能命中旧缓存,脚本请求因为带了随机参数而回源,看到新内容。反过来,如果脚本请求固定命中缓存,静态请求回源,也会出现相反结果。
实际动作:对同一路径分别发起带缓存绕过参数和不带参数的请求,记录每次的响应正文与缓存标记。如果带参数与不带参数结果不同,而源站文件只有一份,那么差异来自缓存层,不是 robots.txt 规则本身。下一步应处理缓存刷新或统一请求条件,再重新比对。
第二种成立条件是:脚本渲染链路里存在额外处理,例如请求头改写、内容替换、代理转发或客户端解析。此时两边拿到的可能不是同一份文本。
区分它的证据是原始响应与脚本最终输出的逐行差异。可以先把脚本拿到的原始响应保存下来,再和静态请求的正文逐行比对。如果原始响应一致,但脚本处理后的结果不同,问题在脚本逻辑;如果原始响应本身就不同,问题在请求路径或服务端分发。
常见触发点包括:脚本自动跟随重定向、自动补全协议、自动添加语言或用户代理头、对文本做编码转换。这些动作都可能让同一路径返回不同内容。定位时应把脚本的请求配置打印出来,与静态请求的配置并排核对,而不是直接怀疑 robots.txt 写错。
可以按下面顺序做,每一步只改变一个条件:
这个实验的价值在于:它能告诉你差异发生在请求阶段、传输阶段还是解析阶段。只有确定阶段,后续动作才有方向。假设两边正文完全一致,只是脚本解析后把某条规则判断反了,那么修改 robots.txt 不会解决问题,应该检查脚本的解析逻辑和匹配顺序。
如果确认是缓存导致,下一步是统一缓存策略并重新验证,而不是反复改规则。如果确认是脚本改写导致,下一步是修正脚本的请求或解析逻辑,再用同一组对照实验复测。如果确认是源站按请求特征返回不同内容,下一步要判断这种差异是否符合预期,以及是否会影响爬虫对规则的理解。
需要提醒的是,robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录。静态响应与脚本渲染结果不同,只能说明两边读取路径不同,不能单独证明某条规则已经生效或失效。把差异定位清楚,再决定改缓存、改脚本还是改规则,顺序才不会反。