robots.txt两条规则撞车,赢的不是先写的那条
本文目录
- 一份robots.txt里,两条规则撞上同一个地址有多常见?
- 撞车不是语法错误,语法检查器一个字都不会提
- 157份文件的口径是怎么定下来的
- 只看对Googlebot生效的那一组
- 6571条代表路径,2378条撞车
- 剩下90个站为什么一次都没撞
- rituals的324条规则是怎么堆出来的
- 撞车率高的站,有一个共同的组织特征
- 撞上的时候,规范说谁赢?
- 比的是字符数,不是行号
- 长度一样的时候才轮到Allow优先
- 2378次对撞,Disallow赢了65.2%
- Allow赢下来的那些地址长什么样
- 换一种长度算法,结论会变吗
- 把裁决规则记成一句话
- 把规则顺序整个打乱,结论会跟着变吗?
- 实验设计:每份文件洗牌五次
- 32815次比对,零次改变
- 但换一种读法,1644条会当场翻盘
- 分歧最集中的几个站
- 哪种读法才算合规,这事有过变化
- 顺序不重要,但注释的位置很重要
- 写下去的1113条Allow,有多少条其实没起作用?
- 判定方法:把它删掉,看结论变不变
- 296条空转,占全部Allow的26.6%
- 空转的原因几乎只有一种
- 45个站写了Allow: /
- 空转不等于有害,但它是个信号
- 一个星号写进去,这份文件还是同一个意思吗?
- 规范要求支持,但规范只管得了2022年之后
- 把不支持通配符的读法跑一遍,3535条判定变了
- 受影响最重的是参数拦截那一类
- 美元符号只有26条,说明大家都不太敢用
- 星号写在开头的那批,其实是多余的
- 要不要为老爬虫单独写一套规则
- 路径里的大写字母、美元符号和百分号,谁最容易让规则落空?
- 路径匹配区分大小写,894条规则带着大写字母
- 带大写不等于写错,但它把风险抬高了
- 百分号编码这一层,规范说得很清楚但很少有人照做
- 末尾那个斜杠,决定了你挡的是目录还是前缀
- 空的Disallow值是允许,不是禁止
- 这四种细节里,哪一种最值得先查
- 这些规则到底是你写的,还是平台替你写好的?
- 规则集完全相同的站有14个
- 更普遍的是同一套骨架加几行自定义
- 重复规则是叠加维护最直接的证据
- 平台默认与自定义规则撞车,责任在谁
- 平台侧也在悄悄改这份文件
- 为什么所有robots.txt检测工具都不报这类问题?
- 工具查的是语法,冲突是语义
- 更根本的原因:工具不知道该拿哪些地址去试
- Google Search Console的robots.txt测试也只测单个地址
- 把官方解析器搬到本地跑,是最省事的一条路
- 拿自己的站跑一遍,该按什么顺序查?
- 第一步:确认爬虫读到的是哪一组规则
- 第二步:把真实地址而不是规则拿来测
- 第三步:反过来查,被挡的地址是不是你想挡的
- 第四步:把冲突判定跑出来,只看结论和预期不一致的那些
- 第五步:把平台默认那份单独存一份
- 做完这五步,剩下的事情就交给日志
- 这套顺序在多站场景下怎么排期
- 量这批数据的时候,尺子坏在哪几处?
- 第一次:解析器的分组逻辑写错了,Allow数量差了三倍
- 第二次:分母差点又用错
- 第三次:代表路径这个办法本身有边界
- 还有一个中文变量名的低级坑
- 还有一处没能量成的东西
- 为什么要把这些写出来
- 一份能被复现的清单该包含什么
- 规则写得越多,越接近你想要的结果吗?
- 规则条数和冲突数几乎是线性的
- 规则多不等于控制得细
- 那么多少条才算合适
- 真正该问的不是数量,是这件事该不该用这个文件做
- 删规则比加规则难,这是它变长的根本原因
- 除了robots.txt,同样的仲裁问题还出现在哪里?
- 同一份响应里,两个字段说相反的话
- 同一个地址,几个层各有一份声明
- 新的声明层还在往上加
- 判断谁赢的通用问法
- 写规则的人不是裁判,这是本文唯一想说的事
- 常见问题解答
- Allow和Disallow同时匹配一个地址,到底哪条生效?
- 把Allow写在Disallow前面,能让它优先吗?
- Allow: /这一行有用吗?
- robots.txt的路径区分大小写吗?
- 不支持通配符的爬虫会怎么读我的规则?
- 怎么在自己站上验一遍这些结论?
- 这份文件多少条规则算合理?
- 权威参考资料
摘要:把157份电商站的robots.txt按RFC 9309的规则跑了一遍,6571条代表路径里有2378条同时被Allow和Disallow命中,占36.2%,牵涉67个站。撞上之后谁赢,规范写得很死:路径写得更长的那条赢,长度一样才轮到Allow。我把每份文件的规则随机打乱五遍、跑了32815次判定,结论一次都没变——顺序在这件事上完全不起作用。可要是换成一部分老爬虫用的先命中先算读法,1644条路径的结论会当场反过来。另有296条Allow(占全部1113条的26.6%)删掉之后判定纹丝不动,它们放行的是本来就没被挡住的地址。
八月中旬那几天,SEO圈子里传得最广的一条消息是OpenAI关于ChatGPT抓取器的一句表态:ChatGPT里由用户点击触发的那次抓取,robots.txt的规则可能不适用。争的是解释权——同一份文件,你当它是禁令,对方当它是给批量爬虫看的,而不是给某个人的一次点击看的。
这句话让保哥想起手头一批没跑完的数据。争解释权这件事,其实根本不用等到AI公司下场。同一份robots.txt,摆在同一个Googlebot面前,只要文件里有两条规则同时够得着一个地址,就已经存在两种以上说得通的读法了。而绝大多数写规则的人,从没读过那张裁决表。
所以我把两周前抓下来的那批文件重新翻了出来,写了一个严格照着RFC 9309实现的匹配器,把每一份文件里的每一条规则都当成一次庭审来跑。下面是结果。
一份robots.txt里,两条规则撞上同一个地址有多常见?
先说清楚撞上指的是什么。robots.txt里的每一条Allow或Disallow,后面跟的都是一个路径模式。模式和模式之间没有任何互斥要求,写成什么样都合法。于是同一个地址完全可能被好几条规则同时匹配到,有的说放行,有的说拦下。
同一批157份文件我还量过另一件事,有多少条指令压根没有接收方在读的比例比想象中高得多。
这份文件一旦写废了后果并不小,整站从谷歌搜索结果里消失的那类事故多半就是从一行规则开始的。
撞车不是语法错误,语法检查器一个字都不会提
这是这类问题最难被发现的原因。你把文件贴进任何一个robots.txt校验工具,它检查的是字段名拼没拼对、有没有写在User-agent组里面、路径是不是以斜杠开头。这些全过了,工具就说没问题。
这类只查表面不查逻辑的毛病到处都是,页面结构分析工具能揪出的六个维度短板也是同一种边界。
生成器给的预设也未必跟规范对齐,通配符判定会和标准打架的那几种情形值得在照抄之前先看一眼。
但校验器不会告诉你:第14行那条Allow,和第112行那条Disallow,管的是同一批地址,而且第112行赢了。它甚至没有这个概念——单看每一行,两行都是完全正确的规则。
这就把问题推到了一个很尴尬的位置。语法层面有工具兜底,逻辑层面没有;而真正会让页面掉出索引、让抓取预算白烧的,全是逻辑层面的事。前者是几秒钟就能查完的东西,后者需要有人坐下来把整份文件想一遍,于是它永远排在待办清单的最后。
顺带说一句,这也是这类问题在SEO工具报告里长期缺席的深层原因。工具的商业逻辑要求每一条发现都能落到一个具体位置、给出一个具体动作;而规则冲突给不出这两样,它只能说这一组规则的合并效果和你的预期可能不一致,然后把判断权交回给人。这样的结论没法做成告警,也没法做成评分,于是它就消失了。
157份文件的口径是怎么定下来的
样本来自一批做得比较成熟的海外电商与消费品牌站,抓取时间是2026年8月16日。抓回来的原始响应有198份,但能进分母的只有157份。中间剔掉了两类:一类是抓取记录里状态码不是200的,服务器把403、429的错误页面也写进了文件;另一类是状态码给了200、内容却是一整页HTML的,那是边缘防护返回的拦截页,不是规则文件。
用别人的工具之前更该先校准口径,第三方数据到底准不准的六步校准法能挡掉大部分噪声。
同一批样本上做过的另一项实测是,给单个爬虫开组会丢掉通配组全部规则,中招比例高得离谱。
这个口径我上一批就踩过一次坑:拿目录里的文件数当分母,数出来是161,比真值多了4份。分母必须从抓取记录里的状态码清单来建,不能从落盘的文件来建。
多说一句为什么必须这么较真。这类文章里所有的百分比都挂在分母上,分母虚高4份,每个比例都会被系统性地压低两三个百分点。单看一个数字察觉不出来,但如果拿它和别的批次做对比,趋势就假了。分母是整篇文章的地基,地基歪一厘米,屋顶歪一米。
还有一个细节值得提前说明:本文所有统计都以Googlebot为观察对象,换成别的爬虫名字重跑,分组结果会不一样,数字自然也会变。之所以选它,是因为它是唯一能在官方后台里当场验证判定结果的对象,别的爬虫我没有办法核对自己的解析器算得对不对。这也是做这类普查时的一条原则:能被独立验证的口径,优先于看起来更全面的口径。
只看对Googlebot生效的那一组
还有一层筛选容易被忽略。robots.txt是按User-agent分组的,一个爬虫只会执行它匹配到的那一组,别的组的规则跟它没关系。所以统计之前,我先对每份文件跑了一次分组选择:有没有专门写给Googlebot的组?有就只用那一组;没有才回落到通配组。
分组之外还有例外条款要留意,通配组的星号对广告爬虫不生效是最容易被漏掉的一条。
要弄清对面到底是谁再谈规则,120种爬虫标识的分类与真假验证是一份可以直接照做的清单。
157个站里有22个给Googlebot单开了一组。剩下的135个走通配组。最后进入统计的规则是5494条Disallow加1113条Allow,中位数是每站41条,最多的rituals.com写了324条,最少的一条都没写。
如果跳过这一步,直接把文件里所有的Allow和Disallow一锅端进统计,得到的数字会大得多,但那个数字不对应任何一个真实爬虫的处境。它是一份文件的总字数,不是任何一个读者读到的内容。这两件事在robots.txt里差得非常远,因为分组之间是互斥的,不是叠加的。
6571条代表路径,2378条撞车
怎么判断一条规则会不会跟别的规则撞上?我的办法是给每条规则生成一个代表路径:把路径里的星号换成一段不会撞车的字符,去掉结尾的美元符号,得到一个这条规则一定能匹配的具体地址。然后拿这个地址回头去问整组规则:有多少条能匹配它?
需要被挡住的地址里最难缠的是筛选组合,分面导航产生的海量URL怎么治理我单独拆过一遍。
这几千条禁止规则最终服务的目标是预算,抓取预算优化的十二项实操按优先级排过一次序。
去重之后一共6571条代表路径。其中2378条被至少一条Allow和至少一条Disallow同时命中,占36.2%,分布在67个站上。也就是说,每三个地址里就有一个处在两条规则的交叉火力下。
| 口径 | 数值 | 说明 |
|---|---|---|
| 进入统计的站 | 157 | 抓取记录状态码为200且内容不是HTML |
| Disallow条数 | 5494 | 只算对Googlebot生效的那一组 |
| Allow条数 | 1113 | 写过Allow的站74个 |
| 代表路径 | 6571 | 每条规则生成一个,去重后 |
| 撞车路径 | 2378(36.2%) | 同时被两类规则命中 |
| 涉及站点 | 67 | 占样本的42.7% |
这张表里最值得盯住的是第三行和第五行的关系。1113条Allow分布在74个站,而撞车路径有2378条分布在67个站——撞车数远多于Allow数,说明一条Allow平均会跟两条以上的Disallow发生交叠。精细放行从来不是一对一的,你放行一个地址,实际上是在跟一整片禁令区域谈判。
另一个容易被忽略的口径问题是去重。6571条代表路径是去重后的数字,去重前是7000出头,差额来自同一份文件里写了两遍的规则。去重这一步必须做,否则重复规则多的站会在统计里获得双倍权重,把整体比例往它那边拽。
剩下90个站为什么一次都没撞
因为它们压根没写Allow。1113条Allow集中在74个站手里,另外83个站的文件里全是Disallow。没有Allow就不存在放行与拦截的对撞,所有地址的命运只有一条路:被某条Disallow匹配到就是拦,匹配不到就是放。
筛选参数该怎么分类处理是个老问题,五类过滤器参数的处理方式对比给了可以直接抄的表。
至于哪些页面真的该挡,电商该屏蔽的七类页面与Shopify实操里有逐类的判断依据。
这也解释了一个现象——撞车集中在那些看起来最讲究的文件里。写Allow说明这个人知道robots.txt有精细控制的能力,而恰恰是这批人最容易掉进裁决规则的坑。什么都不写的反而不会错。
这个结论有点反直觉,也不该被拿去当成不作为的借口。它真正说明的是:能力越强的工具,误用的代价越大。Allow这个字段的存在意义就是在大范围禁止里开一个小口子,而开口子这件事本身要求你精确知道禁止的边界在哪——大多数人并不知道,因为那条禁令往往不是他写的。
这里还藏着一个容易被当成好消息的坏消息。83个站一条Allow都没写,说明它们的规则是纯粹的黑名单模式——凡是没被禁的都放行。这种模式确实不会内部打架,但它同时意味着这些站从来没有做过精细控制:所有的筛选参数、所有的会话地址、所有的打印版页面,要么被一条粗规则整片挡掉,要么完全不管。粗糙和无冲突是同一件事的两面。
另外值得一提的是,这83个站里有不少是规模相当大的品牌。规模和精细度之间并没有必然联系——决定要不要写Allow的,往往只是当年建站那个人的习惯,以及之后有没有人真正接手过这份文件。
rituals的324条规则是怎么堆出来的
规则最多的那个站值得单独看一眼。324条里有78条Allow,撞车路径135条——一个站就占了全样本撞车量的5.7%。翻开文件能看出堆叠的痕迹:先是一批按语言前缀写的目录禁令,然后是一批带查询参数的过滤规则,再往后是一批针对具体促销活动页的临时补丁。
资深团队反而更容易栽在结构性问题上,被忽略的那几类技术SEO失灵原因说的就是这种局面。
这类没人报错的欠账攒起来相当可观,技术债怎么排查和分批偿还给了一套可执行的顺序。
这种文件不是某一天写成的,是三四拨人隔着几年往上叠的。每一拨人只看自己那几行对不对,没人跑过整份文件的合并效果。而合并效果恰恰是爬虫唯一会看的东西。
顺着这条线还能看出一个组织问题。促销活动页的补丁说明写规则的人是运营,语言前缀的禁令说明写规则的人是国际化团队,参数过滤说明写规则的人是技术。三拨人共用一个文件、没有共用的评审,这个文件的最终行为就成了没有人负责的东西。
撞车率高的站,有一个共同的组织特征
把67个撞车站和90个零撞车站放在一起对比,能看出一条界线:撞车站几乎全是有独立技术团队、做过国际化、上过筛选导航的中大型站;零撞车站要么规模小、要么全站结构极简。这不是能力差异,是复杂度差异。
推不动改动往往不是技术问题,甲方拒绝SEO建议八成源于身份冲突给了一套重写汇报的办法。
跨团队协作这件事有具体抓手,后端工程师配合SEO的七个动作点是从二十二周账本里总结的。
复杂度带来的不只是规则变多,还有决策链变长。一条禁令从提出到写进文件可能经过运营、SEO、前端三道手,每道手都对它做了一点修改,最终那一行长什么样谁也说不准。而裁决只看最终那一行。
撞上的时候,规范说谁赢?
这就是整件事的核心。答案在RFC 9309关于规则优先级的条款里,一句话:匹配到的规则里,路径写得最长的那条生效;如果最长的有好几条且方向相反,Allow赢。
涉及取舍的场合还有一张速查表,301、302、404和410各自该在什么场合用能省掉不少争论。
这件事该用哪个手段也常被搞反,robots.txt和meta robots各管哪一段里分工写得很清楚。
比的是字符数,不是行号
规范里比的是规则路径的字符长度,跟它写在文件的第几行毫无关系。这一点和绝大多数人的直觉是反的。程序员看到一组规则,第一反应通常是防火墙那套——从上往下匹配,先命中先返回;或者反过来,后面的覆盖前面的。robots.txt两条都不是。
配置每次reload都通过不代表没事,Googlebot每八次抓取就有一次撞在301上是同一类隐形代价。
服务器上那些数值型配置同样值得逐条问一遍,服务器配置影响SEO的二十项清单可以照着核对。
举个最直白的例子。文件里写着Disallow: /products/ 和Allow: /products/sale/,那么/products/sale/summer这个地址会被放行,因为Allow那条的路径长了6个字符。把两行的位置对调,结果完全一样。
为什么规范要这么设计,其实有道理可讲。robots.txt是给成千上万个互不相识的实现去读的,如果裁决依赖顺序,那么任何一次编辑器的自动排序、任何一次配置管理工具的合并,都可能悄悄改变整个文件的语义。用长度做裁决依据,文件就成了一个跟排列无关的集合,这对分布式的、无人对账的场景是更稳的选择。
长度一样的时候才轮到Allow优先
规范给的第二条裁决是:长度打平时,允许优先于拒绝。这条在真实文件里几乎用不上——我在157份文件里找同一路径既写Allow又写Disallow的情况,一处都没找到。没人会那么写,因为那看起来太明显是自相矛盾了。
把它当访问控制的代价有多大,测试站被谷歌索引后的八步清除与四层防御是最直观的样本。
真要拦住某类程序得分层做,robots、UA识别、WAF三层的选型框架比只改一个文件靠得住。
真正吃掉人的不是打平,是差一两个字符的那种。差一个斜杠、多一个星号,胜负就换了边。
这条规则还有一层现实含义:当你不确定该不该放行时,规范的默认倾向是放行。robots.txt从设计上就不是一个安全机制,它是一份君子协定,遇到歧义时倾向于让内容被看到,而不是倾向于藏起来。把它当访问控制来用的人,都会在这一点上吃亏。
说到这里得澄清一个常见的误解。有人以为robots.txt的默认倾向是禁止,理由是这个文件叫排除协议。恰恰相反:没有任何规则命中的地址一律放行,这是规范写死的行为。文件叫排除协议,是因为它的用途是排除,不是因为它的默认值是排除。
这个默认值决定了很多事情。它意味着你不写规则的地址全都是开放的,也意味着规则文件损坏、返回500、或者被防护挡住时,爬虫的行为不是保守地全站不抓——各家实现不同,有的会沿用上一次缓存的版本,有的会当成没有规则从而全站放行。想清楚这一点,就不会把robots.txt当成访问控制来用了。
还有个更实际的问题:这个默认值意味着遗漏的成本远高于写错的成本。你少写一条规则,那片地址就是全开放的;你写错一条规则,最多是挡错了地方。所以做审计时该先查有没有该挡没挡的,再查有没有挡错的——两者的排查顺序不该反过来。
2378次对撞,Disallow赢了65.2%
把这2378条撞车路径逐条判决,结果是Disallow赢1551次、Allow赢827次。也就是说,三分之一的对撞里,那条Allow是真的起了作用,把一个本来会被挡住的地址救了回来。
解释不同会直接反映到报告上,抓取报告里五类问题URL的占比与排查顺序能帮你分清是谁的问题。
挡与不挡最终都会落到索引规模上,大量无用页面拖垮流量的诊断与处置有一张决策矩阵。
| 裁决结果 | 条数 | 占比 | 含义 |
|---|---|---|---|
| Disallow胜出 | 1551 | 65.2% | 写Allow的人没能达到目的 |
| Allow胜出 | 827 | 34.8% | 精细放行确实生效了 |
要留意的是,Disallow赢的那1551次并不都是事故。很多情况下人家本来就想让那个地址被挡住,Allow匹配上纯属副作用。真正需要人去看的是另一批:写Allow的时候心里想的就是这个地址,结果它没赢。这批混在1551条里,只能靠人工判断意图才能分出来。
还有一件事这张表看不出来:胜负是按路径统计的,不是按流量统计的。一条被误挡的商品列表页和一条被误挡的测试页,在表里各算一条,实际价值差着好几个数量级。所以看完比例之后,务必回头按业务重要性把那些地址排一次序——绝大多数站真正需要处理的,就是排在最前面的那三五条。
Allow赢下来的那些地址长什么样
看几个真实的。aboutyou.com把带各种筛选参数的地址全禁了,然后单独放行了商品详情页上的两个参数,规则写成Allow: /p/*?*firstProductId= 这样。它比通配的Disallow: /*?*firstProductId= 多了三个字符,赢得干净利落。
同一商品的几十个地址该合还是该拆,产品变体的URL与索引策略需要先想清楚再写规则。
这类参数地址到底该不该写禁令,电商筛选URL的三类判别法给了处理策略而不只是结论。
aloyoga.com那组更典型:Disallow把带account、orders、checkout的地址全挡了,再用Allow: /products/account这类规则把商品目录下同名的东西放回来。这些都是真正读懂了裁决规则的写法。
值得注意的是这两组Allow赢得都很险——多出来的只有三到七个字符。这意味着它们非常脆弱:哪天有人把那条Disallow写得更具体一点,胜负立刻反转,而且没有任何地方会报警。把关键放行做成这种一线之差的写法,等于把生意押在别人不会动那一行上。
这两组写法还有个共同点:它们都出现在参数层面而不是目录层面。目录型的放行几乎不会赢,因为目录名通常比通配规则短;参数型的放行经常赢,因为参数名本身就长。想让一条Allow稳稳生效,把它写在尽可能具体的那一层,是唯一可靠的办法。
换一种长度算法,结论会变吗
我顺手做了个对照实验。有人猜测比长度时通配符不该计入,毕竟星号只是一个占位符。于是我用去掉星号和美元符号之后的字面长度重新判了一遍这2378条。
做对照组这件事经常能救命,量出七成页面有差异、补上对照组后只剩两个点就是一次返工。
同一个数字各家算法不同这件事到处都是,关键词难度为什么各家工具差那么大是最典型的一例。
结果是零条改判。这个变量在真实数据上完全不敏感——因为带通配符的规则和不带的,长度差距通常远大于一两个符号。这是个负面结果,但它有用:说明你不用纠结这一点,把星号算进去还是不算进去,答案都一样。
做对照实验的价值也在这儿。一个猜想被数据否掉,比一个猜想被数据支持更省事,因为你从此可以不再考虑这个变量。可惜大多数人只在结果符合预期时才把实验写出来,于是零结果永远没人报告,后面的人接着猜。
把这两条结论合起来看,能得到一个很朴素的操作建议:写Allow之前先确认它有对手,写完之后再确认它赢得下来。两件事都只需要一次判定就能验完。
把裁决规则记成一句话
如果只想记一条,就记这句:谁写得具体谁说了算,一样具体的时候放行说了算。它比最长匹配这个术语更好传达,因为具体这个词天然对应着人的直觉——你专门为某个地址写的规则,当然应该压过那条大而化之的通配规则。
一堆问题先修哪个得有依据,五百个站实测排出来的技术SEO优先级可以当排期底稿。
规则要能传达给非技术同事才有用,内容、技术、外链三类分工与团队配比也是同一个协作问题。
把这句话交给团队里非技术的同事,他们也能判断自己提的那条需求会不会生效。判断不了的那些,正好是需要坐下来一起看的那些。
把规则顺序整个打乱,结论会跟着变吗?
这是本批最让我自己意外的一次验证。既然规范说裁决只看长度,那顺序理论上就该完全无关。理论归理论,我决定直接拿数据砸一遍。
口径不清的指标最容易误导判断,从指标体系到异常诊断的完整做法可以拿来搭自己的框架。
验证一条建议有没有效有个笨办法,给那条建议配一个注定无效的对照组比讲道理管用得多。
实验设计:每份文件洗牌五次
做法很简单。对每一份文件,先按原顺序把所有代表路径判一遍,存下结论;然后把规则数组随机打乱,再判一遍,逐条比对;重复五次。全部157个站跑下来,一共比对了32815次。
想知道某个动作到底有没有增量,别让本来就会买的人冒领功劳那套测法值得借鉴。
抽样口径直接决定结论真假,孤岛页面检测的抽样口径怎么定是同一类方法论问题。
之所以要洗五遍而不是一遍,是因为一次洗牌有可能碰巧没改变关键规则的相对位置。五次独立洗牌把这种巧合的概率压到可以忽略,同时又不至于让脚本跑太久。随机种子写死在脚本里,任何人拿同一份数据都能得到一模一样的结果。
32815次比对,零次改变
一次都没变。这在实验里是最干净的一种结果——它把规则顺序影响结果这个流传很广的说法彻底钉死了。你把Allow写在最上面还是最下面,把新规则追加在文件末尾还是插在中间,对按规范实现的爬虫来说没有任何区别。
这类小脚本自己写最快,用Vibe Coding做SEO小工具的八步避坑讲的就是这种自养工具。
能被机器批量验证的事就别靠人记,哪些SEO工作能交给工具、哪些不能划了一条边界。
顺便说,这也意味着一类常见的优化是白做的:有人为了让某条Allow生效,特意把它挪到对应的Disallow前面。挪了等于没挪。真正该做的是把那条Allow的路径写得更长更具体。
这条结论还有个用得上的地方:既然顺序不影响语义,那么你可以放心地对文件做排序、去重、分组重排,只要不改动规则本身的字符内容,行为就不会变。这让robots.txt具备了可以被自动化整理的性质——很多团队不敢碰这个文件,怕一动就出事,其实动的是排版就完全没风险。
但换一种读法,1644条会当场翻盘
顺序无关只在按规范实现的解析器里成立。我又实现了另外两种读法做对照:一种是先命中先算,从上往下扫,第一条匹配上的规则说了算;另一种是后写的覆盖先写的,扫到最后一条匹配的为准。
判断对面是哪一代程序只能看日志,AI爬虫到底有没有抓你的站那套挖法可以直接套用。
名单上那些名字有没有真来过也能量,266个爬虫令牌里只有23.3%真的来过是另一组实测。
用第一种读法,1644条路径的结论和规范读法不同,牵涉60个站;用第二种,667条不同,牵涉48个站。60个站是什么概念——样本里38.2%的站,命运取决于对面那个爬虫是哪一年写的。
| 读法 | 裁决依据 | 与规范读法的分歧 | 涉及站点 |
|---|---|---|---|
| 最长匹配(RFC 9309) | 路径字符数,打平时Allow优先 | 基准 | — |
| 先命中先算 | 从上往下第一条匹配的 | 1644条 | 60 |
| 后者覆盖前者 | 从上往下最后一条匹配的 | 667条 | 48 |
分歧最集中的几个站
nespresso.com一个站就贡献了84条分歧,rituals.com 52条,接下来是一长串各40条的站——这批站的文件内容高度相似,一看就是同一个平台生成的模板。模板这件事后面单独说。
选平台时就该问清楚默认配置,SaaS托管、自建还是纯代码怎么选把各自的代价摊开了。
模板生成的东西撞车是常态,插件和主题各冒出一套canonical怎么归一是同一类清理。
模板站的分歧数完全一致这件事本身就很能说明问题:它们不是各自写错了,是同一个错误被复制了几十份。追责的话,责任在生成模板的那一方;但承担后果的是每一个店主,而且他们连这份规则长什么样都没看过。
哪种读法才算合规,这事有过变化
2019年之前,robots.txt根本没有正式标准,只有1994年的一份非正式共识文档,那份文档里没有Allow,也没有通配符。所以早年的爬虫按什么顺序算全凭实现者自己决定,先命中先算是当时很常见的一种做法。RFC 9309是2022年9月才发布的,它把最长匹配写成了规范要求。
想靠这个文件拦训练数据更不够用,内容进入模型的四条路在一份诉讼材料里被摊开过。
同一家公司的抓取器也不都守同一套规矩,有一整类抓取器压根不看robots.txt这次改名把它推到了台前。
这意味着一件很现实的事:你面对的爬虫如果是这三年内写的,大概率按规范走;如果是十年前那批还在跑的老程序,它按什么算你无从得知,也没法要求它改。
这里有个判断上的分水岭值得记住。主流搜索引擎和主流AI公司的抓取器基本都跟着规范走,因为它们有明确的合规压力;真正按老规矩跑的,是那些没人维护的采集脚本、监控工具、以及各种一次性写完就长期在线的小程序。而这批程序恰恰不是你想放行的对象,所以规范分歧的实际损失,通常小于它听上去的可怕程度。
顺序不重要,但注释的位置很重要
既然顺序对机器没意义,那它就只对人有意义了。这反而提高了排版的价值:把相关的规则放在一起、用注释行分段、按功能而不是按时间组织,能显著降低下一个人读错的概率。
把口头约定写成文字这件事永远划算,达标定义、违约责任与四类经典纠纷是另一个场景的同一道理。
多人共同维护一份规则文件要立规矩,共享与个人怎么分、规则冲突听谁的是一套可搬用的做法。
注释行以井号开头,爬虫会整行忽略,写多长都不影响解析。样本里用注释做分区的站不到三分之一,而这批站恰好也是撞车最少的那批。相关不等于因果,但至少说明肯写注释的人通常也肯把整份文件读一遍。
写下去的1113条Allow,有多少条其实没起作用?
撞车至少说明Allow参与了裁决。更尴尬的一类是:这条Allow压根没进裁决现场。
有些地址连声明的地方都没有,接口和feed拿什么说自己不想被收录是同一类结构性缺口。
写了放行也未必等于对方进得来,robots说允许、仍有十个站把GPTBot挡在门外是另一层错位。
判定方法:把它删掉,看结论变不变
逐条Allow做一次删除实验。先按完整规则集判它的代表路径,再把这条Allow从规则集里拿掉重判一次。两次结论一样,就说明这条规则的存在与否对结果毫无影响——它是空转的。
在线上做实验要先想好清理,A/B测试怎么做才不影响SEO里有Google的表态和收尾动作。
判断一样东西该不该留有个通用问法,用第一性原理做工具选型说的就是删掉会不会出事。
这个判据比有没有被别的规则覆盖更严格,也更贴近真实价值:一条规则的价值就在于删掉它会不会出事。
这个思路可以推广到任何配置文件。判断一行配置有没有用,最可靠的办法不是读它、不是问写它的人,而是把它拿掉再跑一遍观察输出。能这么验的东西,就不该靠读代码去猜。
296条空转,占全部Allow的26.6%
1113条Allow里,817条有效,296条空转,空转率26.6%。四分之一强。
结构化数据里也有大量白写的字段,112个独立站里17个在犯的商家名称错误是一份对照。
写了不等于有效这件事在别处也成立,132个独立站首页有28个是空壳量的是同一种落差。
换个角度看这个数字:74个站写了Allow,其中58个站至少写过一条空转的。也就是说写过Allow的人里有将近八成,至少有一次以为自己在放行什么,实际上什么也没做。这个比例比条数比例更能说明问题,因为它衡量的是人而不是行。
空转的原因几乎只有一种
我原本以为空转会分成好几类,其中最惨的一类是写了但输了——被一条更长的Disallow压过。实际数据把这个猜想否掉了:被更长Disallow压过的Allow是零条。
有些声明本来就只是提示不是命令,canonical是提示不是指令的八种误用解释了为什么它常常不生效。
两种手段能不能一起用是个高频疑问,noindex和canonical同时用的九种场景怎么判断逐个给了答案。
296条里,285条属于根本没人挡它:这条Allow放行的地址,整份文件里没有任何一条Disallow够得着。robots.txt的默认状态本来就是允许,所以这条规则等于在说请允许一件本来就被允许的事。剩下的11条里,2条是与另一条更宽的Allow重复,9条是几种边角情况。
| 空转成因 | 条数 | 站数 | 解释 |
|---|---|---|---|
| 没有任何Disallow够得着 | 285 | 58 | 默认就是允许,这条纯装饰 |
| 与另一条Allow重复 | 2 | 1 | 更宽的那条已经覆盖了 |
| 其它边角情况 | 9 | — | 空路径、根路径等 |
| 被更长的Disallow压过 | 0 | 0 | 真实数据里一例都没有 |
零这个结果还有一层含义值得展开。它说明真实世界里的Allow和Disallow并不是在同一片区域里贴身肉搏,更多时候它们各写各的,压根不在一个战场上。人们写Allow时想的是一个具体地址,写Disallow时想的是一整类地址,两种思维方式产生的路径长度天然就不在一个量级——具体的那条几乎总是更长,所以Allow只要真的撞上了,赢面就不小。
这也反过来解释了为什么空转率会高达26.6%。既然Allow通常写得比Disallow更具体,那它要么赢,要么根本没对手。没对手的那种就是空转,占了绝大多数。
45个站写了Allow: /
空转里最好认的一种是Allow: /,也就是放行整个站。157个站里有45个写了这一行。它当然不会有任何效果,因为没有这行的默认状态就是全站允许。
不同页面类型该给什么声明有差别,五类页面的meta robots与canonical配置差异可以直接照搬。
虚拟文件和物理文件谁优先也常被搞混,WordPress的robots.txt该怎么写把这两层的优先级讲清楚了。
这一行为什么会出现?多半是从某份模板抄来的,抄的人觉得先声明允许再逐条禁止比较符合直觉。这个直觉在防火墙配置里是对的(默认拒绝,所以要显式放行),在robots.txt里是反的。
更麻烦的是这行会误导后来的人。看到文件开头写着Allow: /,很容易以为下面的Disallow都是在这条总放行的基础上做例外,进而以为删掉某条Disallow就会回到全放行状态。这个理解链条每一环都对,唯独起点那条规则是虚的。
还有一类空转值得单独认一下:写给某个具体文件的Allow,比如放行某张图片或某个脚本。这类规则的出发点通常是担心页面渲染所需的资源被挡住,导致搜索引擎看到的页面是残缺的。担心本身完全正确,但如果整份文件里根本没有一条Disallow够得着那个资源目录,这条Allow就是纯粹的心理安慰。
正确的做法是反过来查:先确认渲染必需的那些资源有没有被某条规则挡住,挡住了才需要写Allow放行。从担心出发写规则,写出来的十有八九是空转的;从实测出发写规则,写出来的每一条都有对手。
空转不等于有害,但它是个信号
说句公道话:296条空转的规则不会造成任何损失,爬虫读到它们只是多花几微秒。真正的代价是别的——它们让文件看起来比实际更精细,让下一个接手的人以为这些地址有特殊安排,也让审计的人多花时间去理解一件根本不存在的意图。
渲染必需的资源被挡会直接丢内容,抓取和渲染DOM分几步、哪一步会丢东西讲得比较完整。
担心资源被挡住是常见动机,Googlebot为什么不读你的preload说明了哪些提示其实无效。
更值得警惕的是它反映的心理状态:写这些规则的人以为自己在做精细控制,实际上没有跑过一次合并判定。同一批人写的那些真正参与裁决的规则,出错概率也不会低到哪去。
所以我一般不建议客户去删这些空转的行——删掉省不下什么,还可能删错。建议做的是在每条旁边加一句注释,写清楚它是哪年为什么加的。注释不会被爬虫读,但会被下一个人读,而下一个人才是这份文件真正的风险来源。
一个星号写进去,这份文件还是同一个意思吗?
通配符是robots.txt里最晚被正式承认的东西,也是分歧最大的东西。5494条Disallow里有3591条带星号,占65.4%;1113条Allow里有732条带星号,占65.8%。三分之二的规则依赖一个在1994年那份原始共识里并不存在的语法。
参数类地址还有专门的处置方案,URL里那个srsltid参数的四种处置办法是一份现成对照。
拿这个文件去解决它管不了的事很常见,用robots.txt拦UTM参数的危害就是一个典型。
规范要求支持,但规范只管得了2022年之后
RFC 9309明确写了:解析器必须支持星号表示任意长度的任意字符,必须支持行尾的美元符号表示路径结束。这是硬性要求,写进了规范的正文而不是附录。
真正吃掉带宽的那批已经换人了,AI爬虫抓取量超过Googlebot好几倍改变了很多决策的优先级。
把日志按对象拆开看会很清楚,八类爬虫标识的二十二周访问账本是一份可对照的样本。
问题在于规范2022年才发布,而互联网上跑着的爬虫程序有相当一批比它老得多。一个2015年写的抓取脚本不会因为2022年出了份RFC就自动学会通配符,它只会把星号当成一个普通字符,去做前缀匹配。
这类程序的数量还不算少。前一批我翻了本站59天的访问日志,光是自称爬虫的标识就有401个不同的串,其中相当一部分是各种监控工具、采集脚本、外链分析器留下的。它们绝大多数不会更新,也没有人对它们的合规性负责。
它们里面还有一批更尴尬的存在:那些号称支持robots.txt、实际只实现了一半的商业工具。做站点审计的桌面爬虫、做外链分析的采集器、做价格监控的比价程序,都会读这个文件,但读的深度参差不齐。你在报告里看到的可抓取判定,取决于那个工具的作者当年读到规范的哪一版。
把不支持通配符的读法跑一遍,3535条判定变了
我实现了第三种解析器:星号和美元符号都当字面字符,规则匹配退化成朴素的前缀比较。用它重跑6571条代表路径,有3535条的结论和规范读法不一样,牵涉133个站——占样本的84.7%。
各家工具读同一个页面结论未必一致,十款技术栈检测扩展的实测对比能看出差异有多大。
桌面爬虫能覆盖的范围有边界,桌面爬虫能查出的十二类问题清单可以对照看缺了哪一块。
这个数字比前面的顺序分歧大得多,原因也直白:一条Disallow: /*?*price_max= 在支持通配符的爬虫眼里能挡住全站带这个参数的地址,在不支持的爬虫眼里只能挡住路径真的以斜杠星号开头的那几个地址——而这样的地址一个都不存在。规则从挡一大片直接变成什么都不挡。
| 解析器行为 | 受影响路径 | 站点数 | 占样本 |
|---|---|---|---|
| 不支持通配符(退化为前缀匹配) | 3535条 | 133 | 84.7% |
| 先命中先算 | 1644条 | 60 | 38.2% |
| 后者覆盖前者 | 667条 | 48 | 30.6% |
三种分歧的性质并不一样。顺序分歧是双向的——有的地址从挡变成放,有的从放变成挡;通配符分歧几乎是单向的——绝大多数是从挡变成放。所以后者的实际风险更明确:你以为挡住的那些筛选页、搜索结果页、打印版页面,在这批老程序面前是敞开的。
还有一个方向的分歧这张表没列:对同一条规则,不同解析器在通配符的贪婪程度上也可能不一致。星号该匹配尽可能长的一段还是尽可能短的一段,在最长匹配的裁决框架里通常不影响结论,但在带美元符号的规则里会。这一类差异我没有在真实文件里找到能触发的例子,所以没有单独统计,只作为已知边界记在这里。
顺带一提,这三个数字的分母都是6571条代表路径,不是页面数。一个站可能有几十万个真实地址落在同一条规则下,也可能一个都没有。所以这里量的是规则的脆弱程度,不是流量的暴露程度,两者需要分开谈。
受影响最重的是参数拦截那一类
nespresso.com有128条、rituals.com 100条、osprey.com 95条。翻开这几个站的文件,密集出现的都是同一种句式:斜杠星号问号星号加一个参数名。这是拦截筛选参数的标准写法,也是最依赖通配符的写法。
站内搜索地址到底该不该禁,四种方案的对比与适用场景讲清了各自的副作用。
参数这件事在内链上也有代价,给内链加UTM参数为什么伤SEO是流量分析与抓取的取舍。
换句话说,各家为了控制抓取预算写得最用力的那部分规则,恰好是在老爬虫面前最容易整段失效的部分。而抓取预算被吃掉这件事,通常正是老爬虫和小爬虫干的。
这就形成了一个很拧巴的局面:规则对守规矩的搜索引擎完全有效,对不守规矩的采集程序完全无效,而你想拦的恰恰是后者。robots.txt作为一个协作机制,本来就只对愿意协作的人有用,通配符这一层只是把这个特性放大了一次。
美元符号只有26条,说明大家都不太敢用
行尾的美元符号表示路径到此为止,用来精确挡住某个具体地址而不误伤它下面的子路径。157份文件里只有26条规则用了它。这个数字低得有点反常——考虑到很多站都想挡住某一个具体页面而不是一整个目录。
路径本身的写法也有讲究,影响抓取与排名的九个URL细节是一份实操清单。
地址结构决定了规则好不好写,扁平URL和层级URL在SEO上到底差在哪值得在改版前想清楚。
我的判断是大家心里没底。星号至少直觉上好理解,美元符号涉及匹配是从头开始还是必须整段相等这层语义,写错了后果是挡多了,风险不对称,所以宁可不写。
不写的代价是精度。想挡住/search这个页面本身、又不想挡/search-tips,正确写法是Disallow: /search$ 加一条;不用美元符号就只能靠祈祷没有别的路径以search开头。样本里确实有站因此把内容页一起挡了。
还有一件事值得说明:这26条美元符号规则里,有几条写在了路径中间而不是末尾。规范只承认行尾的美元符号有特殊含义,写在中间的会被当成普通字符处理。写的人多半以为它是某种分隔符,结果那条规则匹配的是一个真的带美元符号的地址——那样的地址当然不存在。
星号写在开头的那批,其实是多余的
还有个细节值得提。robots.txt的路径匹配天生就是前缀匹配,从路径的第一个字符开始比。所以写Disallow: /*/search和写Disallow: /*/search没区别,但很多人会写成Disallow: */search,少了开头的斜杠。
真出语法级问题时症状反而很明显,一个看不见的字节头就能让页面白屏是另一种极端。
同样的沉默在结构化数据里更狠,一个尾逗号就能让整页标记失效而页面照样正常显示。
按规范,路径必须以斜杠开头,不以斜杠开头的值行为未定义。Google的解析器会给它补一个斜杠,别家未必。这是又一处两种读法都说得通的地方。
类似的还有Disallow: /*,它跟Disallow: /在语义上完全等价,都是全站禁止,但看上去像是在做某种通配。样本里没人这么写全站禁止,倒是有不少人在路径中间加了不必要的星号,让规则变长了几个字符——而长度正好是裁决依据,所以这几个多余的星号是有实际后果的。
要不要为老爬虫单独写一套规则
知道通配符在老程序面前会失效之后,一个自然的想法是:那我把不带通配符的等价规则也写一份,两套并存。这个做法技术上可行,代价是文件长度翻倍、撞车概率同步上升。
边缘防护的效果也没那么确定,防火墙到底拦不拦得住AI爬虫实测出来的答案挺意外。
在服务器上动手要防误伤,拦AI爬虫与限速怎么不把Googlebot一起拦掉有具体的匹配写法。
我的建议是别做。真正会读robots.txt又不支持通配符的程序,数量和危害都不足以让你把文件复杂度翻一倍。要防的话,防在服务器层更直接——按UA或者按请求特征限速,比在一份君子协定里反复叮嘱有效得多。
路径里的大写字母、美元符号和百分号,谁最容易让规则落空?
通配符是明面上的分歧,还有一批分歧藏在更细的地方:大小写、编码、以及路径末尾那个斜杠。这三样都不会触发任何警告,但它们会让一条规则彻底匹配不到任何东西。
编码这件事历史上吃过大亏,搜索引擎抓回去的不是俄语而是一串认不出的字母就是那个年代的账。
本地化和机器可读经常要反着来,正文越本地化越好、结构化数据却要写回国际格式是同一种张力。
路径匹配区分大小写,894条规则带着大写字母
这是最容易翻车的一条。robots.txt里的字段名(User-agent、Disallow)不区分大小写,但路径值区分。写Disallow: /Search挡不住/search。
目录层级深浅同样会影响判断,目录层级URL对SEO有何影响给了六招优化实操。
地址命名习惯有行业惯例可循,一万个站实测出来的URL结构选择能当参照系。
157份文件里有894条规则的路径含大写字母,分布在107个站上——超过三分之二的站至少写过一条。minted.com一个站就有173条,osprey.com 47条,yeti.com 43条。
这个分布本身有信息量:大写字母集中在少数几个站,说明它跟站点的URL设计强相关,而不是随机的手误。用驼峰命名路径的站,规则里自然全是驼峰;全小写站点里冒出一条带大写的规则,那才是真的写错了。
带大写不等于写错,但它把风险抬高了
公平地说,这894条里有相当一部分是对的:站点的URL结构本身就带大写,比如产品编号、语言代码写成zh-CN那种形式。规则跟着URL走,天经地义。
生成器不报错不等于内容对,抽了585条网址、48条是坏的而程序一次都没报警。
声明和真实资源对不上是通病,236条地区声明背后只有6个真页面是一个极端例子。
真正的问题是混用。同一份文件里,一部分路径写成全小写、一部分带驼峰,往往说明这些行来自不同的人、不同的时期,谁都没有回头核对过站点当前的URL到底是哪种写法。而URL的大小写形态是会随着改版变的,规则不会自己跟着变。
验证成本其实很低:从sitemap里拉一批真实地址,看看有没有任何一条能匹配上这条带大写的规则。匹配不上就说明它已经悬空了。这个检查十分钟能跑完,但我几乎没见过谁做。
还有一种混用是跨站抄来的。做多品牌矩阵的团队经常把A站的robots.txt复制到B站再改几行,而两个站的URL命名规范未必一样。复制过来的那些带大写的路径,在新站上一条都匹配不到,却会长期留在文件里充当装饰。这类规则在样本里不少见,判断方法就是拿它去sitemap里搜一下有没有对应地址。
百分号编码这一层,规范说得很清楚但很少有人照做
规范要求:比较之前,规则路径和被检查的地址都要按同一套百分号编码规则归一化。中文路径、带空格的路径、带加号的路径,编码方式不同就匹配不上。
按IP自动跳语言版本的代价很大,半数页面会因此进不了索引是实测出来的结果。
多语言站的地址层坑最多,hreflang、URL与价格结构化数据的三层避坑可以逐项核对。
实际文件里我见到的写法五花八门:有的直接写中文,有的写成百分号加十六进制那种编码形式,还有的写成加号代替空格。这三种写法在不同解析器里的处理不完全一致,尤其是加号——它在查询串里代表空格,在路径段里代表加号本身。
做多语言站的话这一条要格外小心。俄语、阿拉伯语、日语的分类页URL经常带非拉丁字符,浏览器地址栏显示的是可读形式,实际发出去的是编码形式。规则写成哪一种,取决于你是从浏览器复制的还是从日志复制的——而这两处看到的是同一个地址的两副面孔。
还有一种情况是同一个站两种编码并存。老页面的地址是早年编码方式生成的,新页面走了新的编码,两批地址在浏览器里看起来一模一样,字节层面却不同。规则只能匹配其中一批,另一批照抓不误。这类问题几乎只能靠日志发现,因为它在任何静态检查里都是完全正常的。
末尾那个斜杠,决定了你挡的是目录还是前缀
Disallow: /account和Disallow: /account/是两条完全不同的规则。前者会连/accountsettings这样的地址一起挡掉,因为它只做前缀比较;后者只挡目录里的东西。
改版之后最容易出这类问题,一次揪出全站404与重定向链是改完必跑的一步。
批量确认地址还在不在有现成办法,死链怎么批量查出来再分类提交可以直接套用。
这一条在真实事故里出现的频率很高。我见过一个站想挡后台登录页,写了Disallow: /login,结果把/login-help这个专门写来做SEO的帮助页也一起挡了,半年没人发现。
发现它的过程也很典型:不是有人查robots.txt查出来的,是内容团队问为什么那篇帮助文章一直没有自然流量,顺着排查才摸到根上。robots.txt导致的问题几乎都是这个路径被发现的——从业务异常倒推回配置,而不是从配置审计里主动查出。
空的Disallow值是允许,不是禁止
还有一个语法上的陷阱:Disallow后面什么都不写,规范定义为不挡任何东西,等于显式声明全站放行。157份文件里有8条这种写法。
生成器说格式正确的时候,它其实只查了三件事剩下的还得自己看。
同一家族的另一份文件写法讲究更多,2400个站踩出来的sitemap坑基本都在那份清单里。
写这一行的人可能是想留个占位,也可能是删规则时删了一半。它不会造成损失,但如果它出现在一个原本打算全禁的组里,那就是灾难——那个组里别的规则还在,它只是没起到作者以为的作用。
这条规则的历史背景挺有意思:1994年那份原始文档里没有Allow字段,想表达全站放行只能靠写一个空的Disallow。所以它是一个语法上的历史遗迹,今天完全可以用Allow: /代替——虽然那一条同样是空转的。
顺带说一句,这四类问题在自动化检查里都很好实现,判定逻辑都是几行正则的事。真正的难点从来不在技术上,而在于没有人把它排进日常流程——它们不属于任何一个岗位的例行工作。
这四种细节里,哪一种最值得先查
按发生频率排,大小写第一(894条)、末尾斜杠第二、编码第三、空值最后。但按单条造成的损失排,顺序几乎是反过来的:一条误挡了内容目录的末尾斜杠问题,可能比一百条永远匹配不上的大写规则代价更大。
链接结构层面也有类似的一次性体检,一次扒清内外链结构与扣分项适合改版后做。
页面被什么挡在索引外可以一次查清,可索引性体检把几层原因分开列比逐个猜快得多。
所以查的顺序建议按损失排而不是按频率排:先把所有不带末尾斜杠的目录型规则列出来,看看它们会不会波及同前缀的别的路径;再查带大写的那些还匹不匹配得上现在的URL;编码和空值放最后,它们更多是整洁性问题。
这些规则到底是你写的,还是平台替你写好的?
统计到中途,我注意到一件事:一批毫不相干的品牌,撞车数完全相同,都是56条;空转的Allow也完全相同,都是7条。这不可能是巧合。
第三方悄悄改默认值这件事我量过,默认配置发生变更却没人通知的漂移比例并不低。
平台默认给的东西要先认清,Shopify的128种结构化数据类型怎么选也是同一个问题。
规则集完全相同的站有14个
我给每个站的规则集算了个签名——把所有规则排序后取哈希。157个站里,14个站落在4个签名上:7个站共用一份、3个站共用一份、还有两组各2个站。这批是逐字逐句一模一样的文件。
标签页这类批量地址最容易被忽略,Shopify博客标签页怎么避免权重稀释给了处理方法。
平台生成的空页面也要单独处理,集合页没有产品时该怎么办有三种场景的分别处置。
值得注意的是这14个站分属不同的国家、不同的品类、不同的价位段,彼此之间没有任何关系。把它们联系在一起的只有建站平台,或者更准确地说,是同一家代理商用的同一份起手模板。
更普遍的是同一套骨架加几行自定义
完全相同只是冰山尖。更常见的情况是骨架来自平台、末尾追加了几行自己的。前面提到那批撞车数都是56、空转数都是7的站,文件并不完全相同,但前面几十行一字不差。
这种零星失分往往第一年就埋下了,建站第一年最容易失分的十二项配置是同一批经验的汇总。
换架构之后这套基建得自己重搭,sitemap、重定向这些东西不会自动跟过来是常见的上线失分点。
这套骨架来自一个主流的托管电商平台,它给每个店铺自动生成的robots.txt里,本来就包含了一组Allow和Disallow的对撞——平台先用通配规则挡住带查询参数的地址,再用几条Allow把商品目录下的同名路径放回来。设计上是合理的,问题是店主不知道这些规则存在,更不知道自己后来加的那几行会跟它们撞。
| 观察项 | 数值 | 说明 |
|---|---|---|
| 规则集逐字相同的站 | 14个(4组) | 完全套用平台默认 |
| 撞车数相同为56的站 | 十余个 | 共用同一套平台骨架 |
| 同一条规则写了多遍的站 | 9个,共26条 | 叠加维护的痕迹 |
| 规则条数中位数 | 41条 | 最多324,最少0 |
把这张表连起来读,能看到一条从平台到店主的责任链。平台提供骨架,代理商套用模板,店主追加补丁,三方各自只对自己那一段负责,而爬虫读到的是三段合并之后的结果。合并结果没有主人,这才是撞车集中出现在成熟站点上的真正原因——不是因为他们不懂,是因为没有任何一个角色的职责范围覆盖到最终效果。
判断自己是不是处在这条链上有个快办法:把robots.txt的第一行到第十行贴进搜索引擎搜一下。如果能搜到一堆别的站的同款文件,那前面这几十行就不是你的资产,而是你继承来的默认值。
重复规则是叠加维护最直接的证据
26条完全重复的规则分布在9个站上,rab.equipment有8条,peakperformance.com有7条。同一条Disallow在一份文件里写两遍,唯一的解释是两个人在不同时间做了同一件事,谁都没先搜一下文件里有没有。
自动化流程走形是从第二周开始的,那批页面早已进了索引说的就是没人复查的后果。
判断一个站的技术欠账有多深,三类站点的高ROI修复清单可以当成快速评估表。
重复本身无害,爬虫读到两条一样的规则不会有任何异常。它的价值在于当指纹用:一份文件里出现重复,基本可以断定它没有单一的维护者,也没有走过评审。
我做诊断的时候会把重复率当成一个粗糙的组织健康指标。重复越多,说明改这个文件的人越多、彼此越不通气;而这类站的其它配置——重定向规则、结构化数据、埋点脚本——通常也有同样的问题,因为那是同一批人用同一种方式在维护。
指纹这个用法还能反过来用。如果你要评估一个外包团队过去的工作质量,robots.txt是成本最低的切入点之一:有没有注释、有没有重复、有没有明显抄来的行、Allow写得准不准。十分钟看完,大致能判断这批人做事的细致程度,而这个判断通常能推广到他们做的别的东西上。
平台默认与自定义规则撞车,责任在谁
这是个很现实的问题。店主加的那行Allow被平台默认的某条Disallow压住了,或者反过来,店主想挡的东西被平台的Allow放行了。文件是店主能编辑的,但骨架不是他写的,他甚至没读过。
完整的诊断框架能避免漏项,从抓取、内容到AI可见度的审计框架可以当成检查表。
装太多东西之后冲突排查很难做,应用栈精简与冲突排查是一套可执行的清理顺序。
保哥给客户做诊断时,遇到这种情况的第一步永远是:先把平台默认那份原样调出来,跟当前线上这份做一次逐行差分,把哪几行是自己加的圈出来。不做这一步,后面所有分析都建立在这些规则都是我们写的这个错误前提上。
差分之后经常会出现第三种情况:某几行既不在平台默认里,也没人记得是谁加的。这类行最值得单独拎出来做实验——注释掉两周,看日志有没有变化。多数时候什么都不会发生,那它就可以正式退休了。
还有一种更隐蔽的情况:平台把某些规则做成了动态生成。同一个地址在不同时段、不同区域节点上拿到的robots.txt可能不完全一样,因为它是按当前配置实时拼出来的。遇到这种平台,单次抓取的结论不能当定论,必须多点多次采样才有意义。
平台侧也在悄悄改这份文件
还有一层容易被忽略:托管平台会更新它的默认模板,而更新通常不通知店主。你上个月核对过的文件,这个月可能已经多了两行。
定时表达式记不住就用生成器,把sitemap、排名、清缓存交给定时任务是很划算的投入。
存档这件事交给定时任务最省心,把备份、sitemap、缓存、证书都自动化一条龙脚本可以直接改。
应对办法只有一个,就是定期存档。每周把线上那份robots.txt存一份带时间戳的副本,出问题时能立刻做时间维度的差分。这件事用一行定时任务就能做,成本几乎为零,但能省下未来某次排查的整整一天。
为什么所有robots.txt检测工具都不报这类问题?
写到这里应该问一句:这么明显的问题,市面上那么多SEO工具,怎么一个都不提示?
工具的盲区往往正是机会所在,六个工具盲区里的捡漏选词法是同一种思路。
工具选型别只看功能列表,五大类SEO工具的完整推荐与取舍说清了各自的能力边界。
工具查的是语法,冲突是语义
语法检查的边界很清楚:字段名对不对、值有没有、结构合不合法。这些都是单行就能判定的事情。而两条规则会不会撞,必须把整组规则合并起来、针对某个具体地址跑一次完整裁决才知道。这是两个量级的工作。
调试这类文本有专门的顺手工具,把JSON-LD调试这件事讲透省下不少肉眼比对。
生成器只保证语法不保证语义,十三种结构化数据类型一键生成之后仍然要自己核对。
更关键的是输出形态不一样。语法错误可以指着第几行说这里错了,冲突却指不到任何一行——它是两行之间的关系,报告里该怎么写、该标红哪一行,产品设计上就不好办。这大概也是没人做的原因之一。
更根本的原因:工具不知道该拿哪些地址去试
就算工具愿意做合并判定,它也得有一批地址去喂。robots.txt本身不包含任何真实地址,规则里写的是模式不是URL。要测出冲突,工具得先知道这个站有哪些页面——那需要一次全站抓取,或者至少一份sitemap。
另一个地址来源是日志本身,读懂Googlebot抓取与预算浪费那套分析法拿到的是真实请求。
想批量拿到一批真实地址并不难,六种格式的sitemap解析与URL批量提取能省掉手工翻页。
这就是为什么我这次用了代表路径这个折衷办法:从规则自身生成一批一定能匹配的地址,不依赖任何外部数据。它测不出你的真实页面有没有被误挡,但能测出你的规则之间有没有内部矛盾。这两件事需要分开做。
Google Search Console的robots.txt测试也只测单个地址
官方工具确实实现了官方文档里描述的那套完整裁决逻辑,你输一个地址进去,它会告诉你放行还是拦截、哪条规则生效。这个结果是权威的,因为它就是线上那套解析器。
报告里那些状态词各有含义,八种未编入索引状态的决策路径对照着看才不会误判。
官方后台里能挖的东西比想象中多,用过滤器精准拆分品牌流量是个被低估的功能。
但它一次只测一个地址,得你自己想好要测什么。真正会出问题的那些地址,恰恰是你想不到的——你想得到就不会写错了。
这是所有单点检测工具的通病。它能确认你的假设,不能帮你产生假设。而排查这件事里,产生假设才是最难的一步。
把官方解析器搬到本地跑,是最省事的一条路
Google把它的robots.txt解析器开源了,就是线上用的那份C++实现。编译出来是个命令行程序,喂给它一份robots.txt、一个User-agent和一个地址,它吐回允许或拒绝。
自己养一套小工具的杠杆很大,自养工具怎么重塑SEO工作流给了十步可执行路径。
另一条硬边界也能本地复现,Googlebot那个2MB抓取上限怎么测有现成的检查器。
有了这个东西,前面所有实验都能在自己站上复现:从sitemap里拉一批真实地址,批量喂进去,把判定结果和你的预期比一遍。这比任何第三方工具都可靠,因为它不是模拟,它就是本体。
如果懒得编译,照着规范自己写一个也就几十行——核心逻辑只有匹配和比长度两件事。我这次用的就是自己写的PHP版本,跑完之后拿几十个地址跟官方实现对了一遍答案,全部一致才敢往下做统计。这一步千万别省,写解析器最容易在通配符的贪婪程度上出偏差。
拿自己的站跑一遍,该按什么顺序查?
数据看完了,落到自己站上该怎么做。这一节给的是一套顺序,不是清单——顺序比清单重要,因为前一步的结论会决定后一步值不值得做。
开发期就该埋好这些点,自建站开发阶段的十大优化要点能省掉上线后的返工。
从零起步的话顺序更重要,前十二周从技术地基到内容蓝图是一份排好序的清单。
第一步:确认爬虫读到的是哪一组规则
先别看规则内容,先确认分组。用你关心的那个爬虫名字去匹配文件里的每个User-agent值,找出匹配上的那一组。只要匹配上了任何一个专属组,通配组的全部规则对它就不再生效——这是很多人栽的第一跤。
服务端识别对方身份有几种老办法,五种代码识别搜索引擎蜘蛛的实战写法可以拿来验证。
新出现的抓取器要单独认一遍,Google-Agent是什么、怎么识别和应对是最近才需要处理的问题。
确认方法很土但可靠:把文件里所有User-agent行列出来,逐个判断你的目标爬虫会不会匹配上。判断依据是子串包含,不是完全相等。Googlebot-Image会匹配到写着Googlebot的那一组吗?会。所以给Googlebot单开组的时候,图片爬虫也一起被拉进去了。
这一步的产出应该是一张表:左边是你在乎的爬虫,右边是它实际执行的那一组的行号范围。表做出来之后经常会发现,你精心写给通配组的那二十条规则,主流搜索引擎一条都没在读。
第二步:把真实地址而不是规则拿来测
规则之间有没有内部矛盾是一回事,你真正在乎的页面有没有被误挡是另一回事。后者才是生意上的问题,测法是从sitemap里拉一批真实地址出来喂给解析器。
百万级商品的地址怎么组织,分片、进出场与lastmod诚实度是一整套工程实践。
这份文件的作用常被高估,提交网站地图到底能不能提升排名得先把预期放对。
我这次也做了这件事:从143个站的sitemap里拉了26万条地址,每站抽300条跑判定。结论是被自己robots.txt挡住的只有14条,涉及6个站,比例低到0.05%。这是个让我意外的负面结果——自己提交的地址被自己挡住这个经典事故,在这批成熟站点上几乎不存在。
那14条也不全是事故。philips.com有8条落在一个明显是测试用的目录下,theordinary.com那两条指向站内搜索结果页——搜索页进sitemap本来就不合适,被robots挡住反而是对的。真正算失误的没几条。这个结果值得写出来,因为很多审计工具把这一项列为高危,实际数据说明它在成熟站上早就不是主要矛盾了。
抽样口径也得交代清楚。每站至多抽300条,是为了不让sitemap有二十万条的巨型站压过只有几百条的小站。如果不做这个上限,最后的比例基本就是那几个巨型站的比例,跟整体没关系。抽样时用了固定的随机种子,任何人拿同一批数据重跑都会抽到同一批地址。
第三步:反过来查,被挡的地址是不是你想挡的
第二步查的是误伤,第三步查的是漏网。把规则生成的代表路径列出来,逐条问一句:这个地址真的存在吗?我想挡的是不是它?
换成有效手段之后还得等,页面加了noindex要多久才从结果里消失有六个场景的实测。
快速看一眼收录情况有个老办法,site命令怎么用、什么时候会误判得先知道它的边界。
上一批我做过这个实验,结论相当难看:能判定存在性的176条被挡路径里,94条指向的地址已经不存在了,占53.4%。规则还在挡一个早就被删掉的目录,而真正该挡的新目录没人补规则。
这两步合起来才是完整的图景:误伤率低不代表规则健康,它可能只是说明规则太旧、已经够不着任何现存的地址了。一份挡不住任何东西的robots.txt当然不会误伤,它只是彻底失去了作用。
这一步还有个附带收获:跑完之后你会得到一份规则实际覆盖范围的清单,它比文件本身好读得多。把这份清单发给运营和内容团队看,他们经常能当场指出某个目录不该被挡——那些判断只有天天用这些地址的人做得出来,技术这边看规则是看不出来的。
第四步:把冲突判定跑出来,只看结论和预期不一致的那些
前三步做完,最后才轮到本文的主角。对每条Allow做一次删除实验,看它删掉之后判定变不变;对每条规则的代表路径跑一次完整裁决,记下胜出的是哪条。
声明与实测的落差在响应头上更明显,说会变的有3个、真变的有17个是另一组数据。
声明和实际不一致的情况我量过,132个首页有23%自己跟自己矛盾是同一类对照实验。
输出格式建议做成三列:地址、你以为的结果、实际结果。只看第二列和第三列不一样的行。绝大多数站这样的行不会超过十条,一个下午能全部处理完。
难点在第二列。你以为的结果没有任何地方记着,得靠人回忆或者靠猜。所以这一步的真正价值不是当次修了几条,而是逼着团队第一次把每条规则的意图写下来。写下来之后,往后每次改动都能自动比对。
还有个更省力的做法,适合手上有几十个站要管的人:把前四步全部脚本化,输出一份每站一行的汇总表,列上规则条数、Allow条数、空转数、撞车数、误挡数。跑一次十几分钟,之后每月定时跑,只看数字发生变化的那几行。变化本身就是最好的告警——没人改过的文件不会突然多出三条撞车。
第五步:把平台默认那份单独存一份
前面说过,你编辑的那份文件里很可能有一半不是你写的。做完前四步,把当前线上这份存档,再去平台文档里找到默认模板存一份,做一次差分。
另一份长期没人碰的配置也值得存档,重写、缓存、规范化与HSTS六层治理是同样的维护逻辑。
把原始记录留下来是所有排查的前提,日志怎么收集成可检索的结构是一件越早做越好的事。
差分结果建议写进团队文档,注明哪几行是自己加的、为什么加、什么时候可以删。半年后接手的人会感谢这份记录——他至少知道哪些行是可以动的。
差分还有一个副产品:它能告诉你平台什么时候改过默认模板。把每周的存档串起来看,模板变更的时间点一目了然,而这些时间点经常能对上某次说不清原因的抓取量波动。没有存档的话,这类波动永远只能归因为算法调整。
做完这五步,剩下的事情就交给日志
robots.txt的真实效果只有一个地方能验证:服务器日志。规则写完一周后翻日志,看那些你以为挡住了的路径还有没有请求进来,请求方是谁。
限速做在服务器上也有反噬,限速拒掉的第四个请求正好是robots.txt会让全站抓取停十几个小时。
要看清谁在真抓你的站,五千个站样本里的爬虫伪造与预算实测是更硬的参照。
这一步能同时验出两件事:规则有没有生效,以及对方守不守规矩。这两件事经常被混为一谈,但处理方式完全不同——前者要改文件,后者只能上更硬的手段。
翻日志时有个小技巧:不要按路径搜,按状态码和UA的组合搜。被挡住的路径如果还在被抓,日志里通常伴随着一批很有特征的UA;把这批UA单独拉出来看它们还抓了什么,往往能顺手发现别的问题。
还有一个前置动作容易被跳过:先确认这份文件本身能不能被稳定拿到。样本里有20个站的sitemap对着我们的抓取直接返回403,robots.txt本身也有类似情况。如果连文件都拿不全,后面的所有判定都建立在残缺数据上,而这一点在报表里完全看不出来。
这套顺序在多站场景下怎么排期
手上站少的时候,五步一次做完就行。站多的时候建议拆成两轮:第一轮只做第一步和第二步,把分组错配和误挡这两类会直接掉流量的问题清掉;第二轮再做后面三步,那些属于长期整洁性投入,可以按季度排。
排期这件事在大促期间尤其要紧,大促与日常SEO的八维度差异给了完整时间轴。
多站还是单站本身就是个决策,建一个大站还是多个品牌小站的取舍会影响后续所有工作量。
拆轮次的好处是能拿第一轮的结果去换第二轮的资源。分组错配这种问题一旦被量出来,通常能立刻拿到修复窗口;而空转的Allow清理这种事,光靠讲道理很难排进任何一个迭代。
量这批数据的时候,尺子坏在哪几处?
照惯例交代一下这批数字是怎么被我量错又量对的。这一节不是自我批评,是给想复现的人省时间。
监控类工具的口径差异更大,二十款监控工具的评测与选型得先看它们各自怎么算。
同一批域名上做过的另一项实测是,142个站里只有52个回得出304口径同样卡得很死。
第一次:解析器的分组逻辑写错了,Allow数量差了三倍
第一版脚本里,我用了PHP的引用赋值来往分组数组里追加规则,写法看着没毛病,跑起来分组会串。结果是同一个站的规则被分到了错误的组里,统计出来的Allow总数是369条。
有报错反而是好事,这个致命错误的五步排查修复至少有明确的起点。
不报错的故障最难查,从GD库到会话残留的逐层排查是同一种沉默失败。
第二版脚本换成先追加数组、再取引用的写法,同一批文件量出来是1113条。三倍的差距。这种错误最可怕的地方在于它不报错,两个数字都长得很像真的,如果不是我恰好用两个脚本量了同一件事,会直接把369写进结论里。
发现它纯属运气:两个脚本的输出摆在一起,一个说74个站写过Allow,另一个说22个。数字对不上才回头查代码。所以我现在的习惯是关键指标一定用两条独立路径各算一遍,哪怕多花二十分钟。对不上比对得上有价值得多。
第二次:分母差点又用错
上一批踩过的坑这次差点原样重踩:目录里躺着198个文件,直觉上就想拿它当分母。实际能用的只有157份,中间差着41份403和429的错误响应体,以及9份返回200但内容是HTML拦截页的。
换个口径看数据结论可能完全不同,三类站点的聚合自然流量实测就是一次口径切换。
两个数字对不上先怀疑口径,站长工具排名为何与实际不一致给了六步排查法。
教训固化成一句话:分母必须从抓取记录来,不能从落盘文件来。抓取脚本会把失败响应也写进文件,这是它的正常行为,判断哪些能用是分析脚本的责任。
那9份HTML拦截页也值得说一句。它们状态码是200,内容里有完整的HTML结构,如果不做内容检查会被当成一份robots.txt解析——解析结果是零条规则,于是这个站会被统计成什么都没禁。一个防护严格的站,就这样在报表里变成了完全开放的站。
第三次:代表路径这个办法本身有边界
把星号替换成一段固定字符来生成代表路径,这个办法能测出规则之间的内部矛盾,但测不出真实页面的命运。因为生成的地址在站上很可能不存在。
样本量大不代表结论可用,三千条数据揭开的认知差说明该信什么不该信什么。
指标定义清楚才谈得上对比,三个平台三百个站的收录速度实测是一份口径统一的样本。
所以本文里所有百分之多少的路径说的都是规则层面的比例,不是页面层面的比例。这两个口径差得很远,后者我另外用sitemap的真实地址跑了一遍,就是前面那个0.05%。混用这两个数字会得出完全错误的结论。
写文章的时候我特意在每个百分比后面都标了口径,看着有点啰嗦。但这类数据一旦被人引用,标注就是唯一能防止它被误读的东西——引用的人不会回头看你的方法论,他只会摘走那个数字。
还有一个中文变量名的低级坑
写统计脚本输出的时候,PHP的双引号字符串里如果变量名后面紧跟中文标点,那个标点会被当成变量名的一部分——PHP允许高位字节出现在标识符里。于是输出变成一片空白,还附赠一个未定义变量的警告。
还有更隐蔽的改写发生在浏览器里,自动翻译把yes改成forks而数据看不出异常是同一种沉默污染。
脚本层面的小疏忽代价可能很大,上传目录还能跑PHP的五种加固写法是另一类低级但致命的问题。
这个坑我这批犯了两次,第二次才反应过来。修法是所有插值一律写成花括号包裹的形式。听起来微不足道,但它会让一屏统计结果里最关键的那个数字消失,而你正忙着看别的行。
还有一处没能量成的东西
我本来想量一件更有意思的事:一条规则在文件里躺了多久。如果能拿到历史快照,就能算出那些空转规则的平均年龄,进而说明它们是不是随时间自然沉积的。可惜公共存档接口在这台服务器上取不到数据,这条路走不通。
监控闭环怎么搭是个通用问题,四步把引用率监控做成闭环可以套到别的指标上。
想追时间维度的变化得先有数据源,各家波动追踪工具与解读流派各有各的取数方式。
退而求其次的替代方案是看重复规则和注释密度,两者都能间接反映沉积程度,但都不如时间维度直接。这一项留给以后有条件的时候补,写在这里也算给自己留个记号。
这个记号还有个用处:它提醒读者本文的结论有时间边界。所有数字都是2026年8月16日那一次抓取的快照,规则每天都在被人改动。半年后重跑同一套脚本,比例大概率会变,而变化本身才是更有意思的数据。
为什么要把这些写出来
因为这类文章最大的风险不是结论错,是结论看起来对。5494和8624这两个数字放在文章里都很有说服力,读者没有办法判断哪个是对的。
数据分析入门先建立习惯,三类工具与排名追踪的日常做法比学工具更重要。
把过程写出来比只给结论有用,从AI搜索到结构化数据的实施策略也是一步步摊开的。
唯一能让人放心的做法是把口径、剔除规则、失败过程全部摊开,让人能照着复现。数字本身不值钱,能被复现的数字才值钱。
还有一个原则是这几批做下来最有用的:任何一个要写进结论的数字,都必须能追回到某一行原始数据。做不到这一点的数字,宁可不写,也别让它出现在表格里——它一旦被印出来就会被当成事实,而你自己都不知道它是怎么算出来的。
一份能被复现的清单该包含什么
如果你想把本文的实验原样跑一遍,需要的东西一共四样:一份抓取记录(含状态码),一批robots.txt原始响应,一个照规范实现的匹配器,以及一份随机种子写死的洗牌脚本。前两样决定分母,后两样决定结论。
把流程沉淀成模板能省很多重复,四大类三十多个提示词模板可以直接拿去改。
批量取数这件事可以完全脚本化,用Python批量抓关键词数据是一个可直接跑的例子。
四样里最容易被省掉的是第一样。很多人抓完就直接读文件了,没有单独记状态码——而这正是我两次踩坑的根源。抓取和分析必须分成两个阶段,中间用一份记录连接,这是这类普查唯一靠谱的结构。
规则写得越多,越接近你想要的结果吗?
把157个站按规则条数排开,能看到一条很清楚的规律,而它跟大多数人的预期是反的。
把力气花在刀刃上更重要,二十个提升电商排名与营收的进阶策略按投入产出排过序。
结构决定了要写多少规则,架构搭错了爬虫根本找不到商品页是更上游的问题。
规则条数和冲突数几乎是线性的
规则最多的十个站,撞车数也是最多的十个站里的九个。rituals.com 324条规则对应135条撞车,nespresso.com 217条对应84条。反过来,规则在20条以内的站,撞车数基本是零。
分页方案选错会连累一大片,五种分页方案的对比与配置可以先看结论再动手。
分页地址是规则膨胀的常见来源,集合页分页的索引判断与canonical设置有具体做法。
这不是什么深刻的发现,但值得说破:每加一条规则,它跟已有规则撞上的可能性就增加一分,而没有人在加规则的时候跑过合并判定。文件越长,你对它的实际行为知道得越少。
反过来看那些只写十几条的站,也不能一概认为是偷懒。有几个站的做法很聪明:只挡确定不该被抓的四五类地址,剩下的全交给页面上的索引指令去控制。这种分工把两个工具各自的能力用在了对的地方,文件短、冲突少、意图清楚。
规则多不等于控制得细
把撞车率和空转率放在一起看更有意思。那些规则上百条的站,空转的Allow也最多。rituals.com 78条Allow里10条空转,nespresso.com 86条里8条空转。
同类页面互相抢位也要治理,五个维度的信号区隔实战是另一种精细控制。
重复内容的成因得先分类,八类成因地图加诊断清单比一刀切的禁令有效。
换句话说,写得多的人并没有因为写得多而写得更准。他们只是把更多的意图表达了出来,而其中一部分意图在合并之后被抵消了、被覆盖了、或者从一开始就落在空处。
这里有个容易被忽略的成本:规则越多,团队里能看懂这份文件的人越少。二十条的时候产品经理也能读;三百条的时候连技术负责人都要花半天,于是没人再读,改动就只能靠追加。追加又让它更长,循环就此闭合。
还有个现象值得记一笔:规则条数排前十的站里,有六个是做多语言多市场的。语言前缀会让同一类地址在文件里出现好几遍——挡一个搜索页要挡二十种语言下的搜索页,于是二十行。这类膨胀是结构性的,不是维护习惯的问题,用一条带通配符的规则本可以解决,但没人敢改那二十行。
那么多少条才算合适
我不太愿意给一个数字,因为它跟站的复杂度直接相关。但样本给的中位数是41条,而做得最干净的那批站通常在10到25条之间,覆盖的无非是购物车、账户、搜索结果、筛选参数这几类。
技术项做满分也未必涨,问题多半出在搜索意图没对齐提醒别把力气全花在配置上。
现在要顾的层比以前多,从AI爬虫到可访问性的42步实战列了完整范围。
一个判断标准比数字管用:文件里的每一条规则,你都能说出它是哪年为了什么加的、以及删掉它会发生什么。说不出来的那些,先注释掉观察两周。
真正该问的不是数量,是这件事该不该用这个文件做
很多长文件的膨胀来自一个误会:把robots.txt当成了万能的控制面板。可它只能做一件事——建议对方别抓某个地址。它管不了收录、管不了展现、也管不了那些压根不看它的程序。
索引控制该做在内容架构上,帮助中心的索引控制与AI引用工程化是一个正面例子。
提交了不收录还有别的原因,抓取与索引机制的分步拆解能帮你定位卡在哪一环。
想让页面不出现在搜索结果里,该用的是页面上的索引指令;想让某类程序进不来,该用的是服务器或边缘层的拦截。用错了工具,规则写得再精细也是在做无用功。
最典型的误用是拿它来藏东西。禁止抓取不等于禁止收录——一个被禁止抓取的地址,如果有别的站链向它,照样可能带着标题出现在搜索结果里,只是没有摘要。想藏的东西被藏了一半,反而更显眼。
还有一种常见误用是拿它来控制抓取频率。文件里能写的那个延迟字段,主流搜索引擎里只有一家会读,别家要么忽略要么按自己的算法调节。想真正压住某类程序的请求速率,只能在服务器或者边缘层做限速,那是另一套完全不同的工具。
还有个折中办法:不删,但把过期规则集中挪到文件末尾,用一行注释标成待清理区。这样既不承担删错的风险,又能让下一个人一眼看出哪些是活的、哪些是存疑的。文件长度没变,可读性完全不同。
删规则比加规则难,这是它变长的根本原因
加一条规则的风险是可以估计的:最坏无非是挡多了。删一条规则的风险是不可估计的:你不知道当年为什么加,删了会不会放出一堆垃圾地址。
有些工具留着不用比乱用强,外链拒绝工具还有没有用的决策框架给了判断依据。
该不该留下一个已经没用的东西,FAQ富结果被砍之后那段标记还写不写是同一道选择题。
于是所有人都只加不删,文件单调增长。破局的办法只有一个,就是给每条规则留下加它的理由。这件事必须在加的当时做,事后再补基本补不回来。
除了robots.txt,同样的仲裁问题还出现在哪里?
最后把视野拉开一点。这次实验测的是一份文件内部两条规则的裁决,但同一条声明有两种读法这件事,在整条技术链路上到处都是。
响应头本身能做的事不少,X-Robots、缓存与Vary的实战机制是一份系统的梳理。
响应头里那些没人读的字段我数过,248个死字段里多数不是你写的而是平台统一下发的。
同一份响应里,两个字段说相反的话
HTTP响应头是重灾区。X-Frame-Options写着拒绝任何嵌套,同一个响应里的内容安全策略却允许自家子域嵌套;缓存指令里同时写着不许存储和存一年。这些组合在规范里都有明确裁决,而裁决结果往往和写的人以为的相反。
安全策略里的白名单同样会失效,白名单上明明写着那个域名、浏览器还是拦了是一次真实排查。
缓存那几个字段的配合最容易写岔,怎么配才能既秒开又不出改了不更新的事故讲得比较细。
Google那边对安全响应头的表态挺有意思:真正跟搜索有关系的只有一类,就是阻止别的站把你的内容嵌进iframe——不管是用老的X-Frame-Options,还是用内容安全策略里的frame-ancestors。这两个恰恰是最容易写出矛盾的一对。
缓存那一对更能说明问题。同一个响应里既写了不许存储,又写了一个很长的有效期,规范的裁决是不许存储胜出——但中间的CDN、代理、浏览器各自实现的严格程度不一样,实际表现可能是三层里有两层照做、一层照存。这种时候你看到的现象是缓存偶尔不更新,排查方向却往往被引到应用层去了。
同一个地址,几个层各有一份声明
再往上一层,一个页面的身份可能同时被四个地方声明:sitemap说它该被收录,robots.txt说它能不能被抓,页面上的meta标签说它要不要进索引,canonical说它是不是正主。这四个声明分属不同的文件、不同的团队、不同的更新节奏。
跨页场景下的冲突形态更多,八种跨页场景与冲突诊断是一份对照表。
最终由谁说了算有明确逻辑,Google选择规范网址的九条决策逻辑可以照着排查。
它们之间没有统一的仲裁者。robots.txt挡住的页面,页面上写的noindex永远不会被读到——因为抓都没抓,怎么读得到那个标签。两条规则叠加的结果,跟任何一方的意图都不一样。
新的声明层还在往上加
八月中旬llms.txt发布了第二版规范,新增了两种正式的链接关系:一种指向页面的Markdown版本,一种指向覆盖这个页面的说明文件,两种都可以写在HTML里,也可以写在HTTP响应头里。
想知道AI爬虫真正在乎什么,从代码逆向出它的抓取偏好比看官方说明更实在。
要进AI的候选池得先过技术这关,五步技术优化的实战顺序把门槛列清楚了。
Google那边的表态很直接:搜索本身不使用这些文件,维护它既不会帮你也不会害你。但这不妨碍它成为第五份声明——而且从第一天起,它跟前四份之间就没有任何一致性检查。
更麻烦的是这五份声明的更新节奏完全不同。sitemap通常是程序每天生成的,robots.txt可能三年没动,页面上的meta标签跟着模板走,canonical由CMS插件控制,llms.txt多半是某次赶时髦手写的。节奏不同意味着它们不可能长期保持一致——不一致不是偶发故障,是这套架构的常态。
还有一类情况是规范写了但实现没跟上,或者实现跟上了但版本参差。这时候四问的答案是不确定,唯一的出路是实测:构造一个能区分两种行为的最小样本,实际发一次请求看结果。这套方法从robots.txt到响应头都通用,区别只在于构造样本的难度。
判断谁赢的通用问法
不管遇到哪一层,判断方法是同一套四问:这条声明的接收方是谁?规范有没有写明并存时的裁决规则?裁决依据是长度、严格度,还是先后顺序?我实际写的那一条,在裁决里排第几?
信号之间打架时怎么定夺,六类消歧信号的管控实战给了处理顺序。
多份声明怎么合成一个实体,@graph与知识图谱怎么搭是另一套合并规则。
能把这四问答完,绝大多数配置明明写了却没生效的问题当场就有答案。答不完的那些,多半是因为规范本身没写,那就得靠实测——而实测的第一步永远是找到那个真正生效的解析器。
这四问里第三问最容易被跳过。人们通常问完接收方是谁、规范怎么说,就以为结束了,其实还差最关键的一步:裁决依据到底是哪个维度。robots.txt比长度,HTTP缓存比严格度,内容安全策略里多份声明取交集,同名响应头按合并规则拼成列表。四种依据,四种完全不同的写法后果,混着记必然记错。
写规则的人不是裁判,这是本文唯一想说的事
回到开头那条新闻。OpenAI说用户触发的抓取可能不适用robots.txt,很多人的第一反应是气愤。但把这件事和本文的数据放在一起看,会发现它只是同一个问题的最外层——你写下一条规则,它的效力从来不由你决定。
规则之外还得想清楚要什么,四大AI搜索引擎的分引擎策略是更靠前的一步。
还有一种思路是干脆换成收费,要不要向AI爬虫按次抓取收钱已经有平台在做了。
决定它的是对方手里那张裁决表。表在规范里的时候,你至少还能查;表在对方的产品决策里的时候,你连查都没地方查。所以能查的那一部分,更值得花一个下午跑清楚。
常见问题解答
Allow和Disallow同时匹配一个地址,到底哪条生效?
按RFC 9309的规定,路径写得更长的那条生效,长度以规则里写的字符数计算,通配符也算进去。如果最长的规则里既有Allow又有Disallow且长度相同,Allow生效。跟这两条规则写在文件的第几行完全无关。
把Allow写在Disallow前面,能让它优先吗?
不能。我用157份真实文件做过验证:把规则随机打乱五遍、跑了32815次判定,结论一次都没变。想让某条Allow赢,唯一的办法是把它的路径写得比对应的Disallow更长更具体,而不是调整行的位置。
Allow: /这一行有用吗?
没有用。robots.txt的默认状态就是全部允许,写不写这一行结果一样。样本里45个站写了它,全部属于空转。它唯一的副作用是会让后来接手的人误以为文件是按先总放行再逐条禁止的逻辑组织的。
robots.txt的路径区分大小写吗?
路径区分,字段名不区分。写Disallow: /Search挡不住/search这个地址。样本里894条规则的路径带大写字母,涉及107个站。如果你的站URL是全小写的,这类规则很可能一条都没匹配上。
不支持通配符的爬虫会怎么读我的规则?
它会把星号当普通字符做前缀匹配,结果是绝大多数带通配符的规则彻底失效。我用这种读法重跑了一遍,6571条路径里有3535条结论不同,涉及133个站。受影响最重的是拦截筛选参数那一类规则,它们几乎全依赖通配符。
怎么在自己站上验一遍这些结论?
把Google开源的robots.txt解析器编译出来,从sitemap里拉一批真实地址批量喂进去,把判定结果和你的预期逐条比对。重点看三类:你以为放行实际被挡的、你以为挡住实际放行的、以及删掉之后判定不变的那些Allow。
这份文件多少条规则算合理?
样本中位数是41条,维护得最好的那批站通常在10到25条。比条数更好用的判据是:每条规则你都能说出它是哪年为什么加的、删掉会发生什么。说不出来的先注释掉观察两周,多数时候什么都不会发生。
权威参考资料
本文标题:《robots.txt两条规则撞车,赢的不是先写的那条》
本文链接:https://zhangwenbao.com/robots-txt-rule-conflict-longest-match-audit.html
版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0