配置 robots.txt 时,最容易出错的一类问题来自规则冲突:既想屏蔽整个目录,又想给目录里的某个子路径开例外。写了 Disallow: /admin/ 和 Allow: /admin/public/ 之后,/admin/public/page 到底能不能被抓?答案取决于两条规则的优先级,而优先级的判断依据是路径长度。
匹配是前缀匹配
首先要理解匹配方式:robots.txt 里的路径匹配是前缀匹配,不是精确匹配。
Disallow: /admin/ 会拦住 /admin/a、/admin/b/c、/admin/ 本身,以及任何以 /admin/ 开头的地址。它不会拦住 /adminx(因为缺少那个斜杠),也不会拦住 /public/admin/。
这个特性让规则写起来很简洁——不需要为每个具体页面写一条,写目录前缀就够了。
但也带来一个问题:如果只想屏蔽目录里的部分内容,前缀匹配就太粗了。这时就需要 Allow 来开例外。
优先级的判断顺序
当多条规则同时匹配一个地址时,按以下顺序判断。
第一,路径更长的规则优先。这是最主要的判断依据。Allow: /admin/public/ 的长度是 14 个字符,Disallow: /admin/ 的长度是 7 个字符,前者更长,所以匹配 /admin/public/page 时,Allow 规则胜出,页面可以被抓取。
第二,路径长度相同时,Allow 优先。这是一个补充规则,用于处理两条规则长度完全一致的情况。虽然这种情况不常见,但规则明确了 Allow 的优先地位。
所以开头那个问题的答案是:/admin/public/page 可以被抓取,因为它的匹配规则中 Allow 那条更长。
通配符与结尾符
除了基本的前缀匹配,还有两个特殊符号。
是通配符,可以匹配任意字符序列。例如 Disallow: /?orderby= 会拦住所有带 orderby 参数的地址,无论前面是什么路径。
$ 表示结尾。例如 Disallow: /*.pdf$ 会拦住所有以 .pdf 结尾的地址,但不会拦住 /doc.pdf.html。
这两个符号在屏蔽带参数的地址时很有用。比如电商站的筛选页往往有大量参数组合,用通配符可以一条规则全部拦住。
需要注意通配符的支持程度:Google 和 Bing 支持 * 和 $,但一些较小的爬虫可能不支持,会把它们当作普通字符。所以如果规则的可移植性很重要,应该避免依赖通配符。
多个 User-agent 组怎么选
另一个容易混淆的点是「有多个组时用哪个」。
规则是:最具体的 User-agent 优先,且只使用那一个组,不会合并。
假设文件里同时有这两组:
User-agent: *
Disallow: /private/
User-agent: Googlebot
Disallow: /nogoogle/
Googlebot 访问时,只会读 Googlebot 组,也就是只受 Disallow: /nogoogle/ 约束,/private/ 对它没有限制。反过来,其他爬虫读 * 组,只受 Disallow: /private/ 约束。
这个「不合并」的特性很重要。很多人以为写了一个 * 组作为通用规则,再针对某个爬虫写特殊规则,两者会叠加生效。实际上不会——特殊组会完全取代通用组。
所以如果希望 Googlebot 同时受两条规则约束,必须在 Googlebot 组里把两条规则都写一遍。
空规则的特殊含义
最后一个高频陷阱:Disallow: 后面留空。
User-agent: *
Disallow:
这个写法表示「不限制任何路径」,也就是允许抓取全站。它与 Disallow: /(注意有一个斜杠)的效果完全相反——后者是禁止抓取全站。
一个斜杠的差别,效果从「全部允许」变成「全部禁止」。所以在写规则时,如果目的是允许全站,用留空的写法或者干脆不写 Disallow 行;如果目的是禁止全站,一定要确认斜杠在。
检查清单
- 路径匹配是前缀匹配,
/admin/会拦住所有以它开头的地址 - 多条规则冲突时,路径更长的优先;长度相同时 Allow 优先
- 用更长的 Allow 规则可以给被屏蔽目录里的子路径开例外
*匹配任意序列,$表示结尾,但部分爬虫不支持,可移植性受限- 多个 User-agent 组时只使用最具体的那一组,规则不会合并
Disallow:留空表示允许全部,Disallow: /表示禁止全部,只差一个斜杠