我们的立场:我们是 Geonode,向数据采集者出售代理服务,因此 robots.txt 直接位于我们客户工作流程的核心位置。 坦率地说,遵守该规则符合您的利益,而不仅仅是该网站的利益。 尊重该文件、进行自我标识并控制爬行速度的爬虫,是网站运营者可以选择允许的。而无视该文件的爬虫则是一种需要被封堵的骚扰,封堵对网站运营者来说成本低廉,对您来说却代价高昂。 我们还希望明确该标准本身对此问题的表述:RFC明确指出这些规则“并非一种访问授权形式”——因此遵守robots.txt是必要条件但非充分条件,而服务条款则是另一个独立的问题。
什么是 robots.txt,什么不是 robots.txt
RFC 文档本身的表述最为清晰:
如果爬虫访问了服务所有者的整个 URI 空间,可能会给服务所有者带来不便。本文档规定了最初由“机器人排除协议”定义的规则,要求爬虫在访问 URI 时遵守这些规则。
这些规则并非一种访问授权形式。
最后一句具有双重含义。它既意味着被禁止的路径并未受到保护——没有任何机制强制执行该规则——也意味着被允许的路径并不因此获得授权,因为授权源于条款和法律,而非文本文件。
安全部分明确阐述了前半部分的内容,值得引用,因为许多人对此理解有误:
《机器人排除协议》不能替代有效的内容安全措施。在 robots.txt 文件中列出路径会将其公开,从而使这些路径可被发现。
因此,Disallow: /admin/secret-reports/ 向全世界宣告了该路径的存在。如果您正在编写 robots.txt,这正是不应在其中列出任何敏感路径的理由——请使用身份验证,这也是 RFC 明确推荐的做法。
格式
一个文件由一系列组构成。每个组以一行或多行user-agent开头,后跟规则。
User-agent: *
Disallow: /admin/
Disallow: /search?
Allow: /search/help
User-agent: BadBot
Disallow: /
Sitemap: https://example.com/sitemap.xml
爬虫必须支持的三个特殊字符:
| 字符 | 含义 | 示例 |
|---|---|---|
# | 行注释 | allow: / # comment in line |
$ | 匹配模式结束 | allow: /this/path/exactly$ |
* | 零个或多个任意字符 | allow: /this/*/exactly |
末尾的空分组具有特殊含义:RFC 指出“最后一个分组可以没有规则,这意味着它隐式允许一切内容”。 因此,尾部为 User-agent: quxbot 且其下无任何内容的写法,将授予该爬虫不受限制的访问权限。
一个没有路径的 空 Disallow: 也意味着允许一切内容——这是表示“无限制”的惯用写法。
Sitemap: 并非核心语法的一部分。 RFC 中的 ABNF 包含一条针对实现者的注释,建议“定义所需的额外行(例如,Sitemaps)”,因此这是一种被广泛支持的扩展,而非必备功能。Crawl-delay 属于同一类别:常见、被许多爬虫支持,但未纳入标准。
User-Agent 匹配原理
比大多数人想象的要更具体,值得深入理解。
该标识符是 User-Agent 头中的一个子字符串。 RFC 中的示例:Mozilla/5.0 (compatible; ExampleBot/0.1; https://www.example.com/bot.html) 这个头对应于 user-agent: ExampleBot 中的 robots.txt 这一行,并指出“产品标识符(ExampleBot)是 User-Agent HTTP 头中的一个子字符串”。
匹配不区分大小写。 “爬虫必须使用不区分大小写的匹配方式来查找与产品标识符匹配的组,然后遵守该组的规则。”
多个匹配组将被合并。 “如果有多个组与用户代理匹配,则必须将这些匹配组的规则合并为一个组。” 因此,同一文件中两个独立的User-agent: ExampleBot代码块会生成一组合并后的规则,而非第二个代码块覆盖第一个。
**最终仅生成一个规则组,而非多个。**如果某个规则组包含您的令牌,则应使用该规则组,并完全忽略*规则组——通配符仅作为备用方案,而非特定规则在此基础上追加的基准。 这一点常让人感到意外:拥有独立组别的爬虫并不受通用规则的约束。
如果完全没有匹配项:“如果没有任何组与产品令牌匹配,且没有包含值为 * 的用户代理行的组,或者根本不存在任何组,则不应用任何规则。”
匹配基于具体性,而非顺序
这是整个领域中最常被误解的一条规则。
为了判断是否允许访问某个 URI,爬虫必须将“allow”和“disallow”规则中的路径与该 URI 进行匹配。该匹配应区分大小写。 匹配必须从路径的第一个八位字节开始。必须使用找到的最具体匹配。最具体的匹配是指匹配的八位字节数量最多的那个。
不是“先匹配者胜”,也不是“后匹配者胜”。最长的匹配胜出。
RFC 中的示例:
User-Agent: foobot
Allow: /example/page/
Disallow: /example/page/disallowed.gif
对于 example.com/example/page/disallowed.gif,Disallow 这一行更长,因此它适用——尽管它出现在第二位,且父路径已被 Allow 覆盖。
即使在文件中反转规则顺序,结果也不会改变。顺序无关紧要。
另外两条规则进一步完善了这一机制。出现平局时,优先采用 Allow 的规则: “如果一条‘允许’规则和一条‘禁止’规则等价,则‘允许’规则‘应’被采用。”而且 未匹配即视为允许: “如果某组规则中未找到与用户代理匹配的规则,或者该组中没有规则,则该 URI 被允许。”
还有一点细节值得了解:“/robots.txt URI 被默认允许”,因此一个禁止所有内容的文件并不会禁止自身。
路径匹配还涉及百分比编码规范化。 ASCII 范围外的字节以及位于保留范围内的字节“在比较前必须进行百分比编码”,而 URI 中经过百分比编码的 ASCII 字节“在比较前必须进行解码”,除非该字节属于保留字符。实际操作中:建议使用经过维护的库,而不是自己编写相关代码。
状态码改变一切
这里的规则非常明确,却经常被忽视,而且其中两条规则之间的差异很大。
成功。 “如果爬虫成功下载了 robots.txt 文件,则爬虫必须遵循可解析的规则。”
重定向。 “爬虫‘应’至少跟随五个连续的重定向,即使跨越不同权威域。”通过五个重定向到达的文件,“必须被抓取、解析,并根据初始权威域的规则进行处理”。超过五个重定向时,爬虫“可”假定该 robots.txt 文件不可用。
不可用 — 4xx。 “如果服务器状态码表明爬虫无法访问 robots.txt 文件,则爬虫‘可’访问服务器上的任何资源。”404 状态码表示无限制。
**无法访问 — 5xx。**这是人们常误解的一点:“如果由于服务器或网络错误导致无法访问 robots.txt 文件,则意味着该文件未定义,爬虫必须将其视为完全禁止。”
5xx 表示完全停止。 不是“照常继续”,也不是“无限期使用缓存副本”——而是完全禁止访问。 RFC 确实允许一种长期例外情况:如果文件“在相当长的一段时间内(例如 30 天)”未定义,爬虫“可以”假设 robots.txt 文件不可用……或者继续使用缓存副本。
解析错误。 “爬虫必须尝试解析 robots.txt 文件的每一行。爬虫必须使用可解析的规则。” 格式错误的行不会使文件失效;你只需使用能够读取的内容。
这对编写爬虫的任何人来说都有实际意义:目标站点出现临时中断时,应暂停爬取,而非加速爬取。若本末倒置,就会对本已不堪重负的网站造成进一步的压力。
缓存与限制
有两项操作要求常会让自研实现陷入困境。
至少每天刷新一次。 “爬虫‘可’缓存获取的 robots.txt 文件内容……爬虫‘不应’使用缓存版本超过 24 小时,除非 robots.txt 文件无法访问。”
在爬虫启动时仅获取一次文件并运行一周的做法不符合规范。网站会更改规则,而长期运行的任务需要及时察觉这些变化。
至少解析 500 KiB。 “解析限制必须至少为 500 基比字节。”大型网站拥有大文件,如果解析器在任意较小的尺寸处截断,将会无声地遗漏规则——这是此处最糟糕的故障模式,因为这会导致爬虫误以为自己符合规范,而实际上并非如此。
读取真实文件
通过一个实际示例进行演示。
User-agent: *
Disallow: /search
Allow: /search/about
Disallow: /*?sessionid=
Disallow: /*.pdf$
Crawl-delay: 2
User-agent: GPTBot
Disallow: /
User-agent: PartnerBot
Disallow:
Sitemap: https://example.com/sitemap_index.xml
逐行解析:
**Disallow: /search
** 会阻止 /search
、/search/
、/search/results
—— 任何以该字符串开头的路径,因为匹配从第一个字节开始,且不存在 $
。
**Allow: /search/about
** 更长,因此对于该特定路径,它优先匹配。决定因素是匹配长度,而非顺序。
**Disallow: /*?sessionid=
** 使用通配符来阻止任何包含会话参数的路径,无论其前缀是什么。
**Disallow: /*.pdf$
** 阻止以 .pdf
结尾的 URL。如果没有 $
,它也会阻止 /report.pdf.html
。
**Crawl-delay: 2
** 是一种扩展规则而非标准规则,遵循该规则是良好的实践。
**User-agent: GPTBot
配合 Disallow: /
** 将完全排除该爬虫。请注意,GPTBot 仅受此规则约束——它不受 *
组的限制,因此上文中的 Crawl-delay
规则对其不适用。
**User-agent: PartnerBot
且 Disallow:
为空 ** 表示授予无限制访问权限。
**Sitemap:
** 指向 URL 列表,这是大多数文件中最具实用价值的行。关于如何处理它,我们已在 如何查找网站上的所有页面 中进行了说明。
在代码中遵循这一原则
使用经过维护的解析器。仅“特异性匹配”规则本身就是常见的错误来源,而百分比编码规范化则更易出错。
Python: urllib.robotparser 位于标准库中,对于简单情况已足够;谷歌的开源解析器 robotstxt 及其 Python 绑定精确实现了 RFC 9309 标准。Scrapy 内置了 RobotsTxtMiddleware,并在新项目中默认启用——请确认无人将其禁用。
**Node.js:**有多个受维护的包实现了该标准。
**Go:**存在遵循 RFC 匹配规则的库。
无论您使用什么,请确保以下四点正确:
每 24 小时刷新一次,而不是仅在启动时刷新一次。 将 5xx 视为完全禁止,将 404 视为无限制。 根据实际的产品令牌进行匹配,并确保 User-Agent 头中包含该令牌。 最多跟随五个重定向,并在原始主机的上下文中应用规则。
还有第五点,虽然未在 RFC 中提及但同样重要:记录跳过的内容。如果爬虫因一条未预料到的规则而默默排除了网站的一半内容,那么直到数周后,当有人质疑报告为何有误时,才会发现这些缺失的数据。
robots.txt 未涵盖的内容
这一点值得明确说明,因为人们往往会从两个方向过度解读它。
它并未说明你可以如何处理获取到的数据。 版权、数据库权利和服务条款均独立适用。
这并非授权。 RFC 已明确指出这一点。允许访问的路径是指网站未要求爬虫避开的路径,这与同意批量采集并非一回事。
标准中并未规定速率限制。 Crawl-delay 是一项扩展。是否保持礼貌取决于您自身。
它不区分用途。 文件无法在标准语法中声明“允许索引,禁止 AI 训练”,尽管许多网站现在通过指定特定的 AI 爬虫令牌来近似实现这一点。欧盟的文本和数据挖掘框架考虑了机器可读的权利保留,而表达这些权利的机制仍在完善中。
**它无法阻止任何人。**这仅是一种请求。实际执行依赖于速率限制、封锁和法律程序——这也是运营商选择允许该爬虫运行,而非被迫阻止它的实际原因。
大家还问
robots.txt 具有法律约束力吗?
本身并不具有。RFC 9309 指出,其规则“并非一种访问授权形式”——这只是要求爬虫遵守的一项请求。 法律义务源于服务条款、版权、数据库权利以及特定司法管辖区的法律,无论该文件内容如何,这些规定均适用。
robots.txt 规则是否按顺序匹配?
不,这是关于该文件最常见的误解。规范要求“必须使用找到的最具体匹配项”,其中“最具体”指字节数最多。最长的匹配项优先,顺序无关紧要,若出现平局则以 Allow 为准。
如果 robots.txt 返回 404 错误会怎样?
该文件“不可用”,RFC 规定爬虫“可以访问服务器上的任何资源”。没有文件即表示没有限制。这与服务器错误不同。
如果 robots.txt 返回 500 状态码会怎样?
该文件“不可访问”且状态未定义,爬虫“必须假定完全禁止访问”。服务器错误意味着必须完全停止,而非继续操作。经过较长时间(RFC 建议为 30 天)后,爬虫可将其视为不可用,或继续使用缓存副本。
我应该多久抓取一次 robots.txt?
至少每 24 小时一次。RFC 规定,爬虫“不应使用缓存版本超过 24 小时,除非 robots.txt 文件无法访问”。仅在启动时抓取一次并运行一周的做法不符合规范。
特定的用户代理组会覆盖通配符组吗?
它会取代通配符组。如果某个组命名了您的产品令牌,则应遵循该组规则,并完全忽略 * 组——具体规则不会附加到通用规则之上。命名相同令牌的两个组将合并为一个。
robots.txt 中的 * 和 $ 分别代表什么?
* 匹配零个或多个任意字符,而 $ 标记匹配模式的结束。这两者都是爬虫必须支持的字符。Disallow: /*.pdf$ 会屏蔽以 .pdf 结尾的 URL;如果没有 $,它也会屏蔽 /file.pdf.html。
我可以使用 robots.txt 来隐藏敏感页面吗?
不可以,这样做反而会适得其反。RFC 规范的安全性章节指出:“在 robots.txt 文件中列出路径会将其公开,从而使这些路径可被发现”。任何人都可以读取该文件。请使用身份验证机制,这是规范中明确推荐的替代方案。
总结
robots.txt 规则简短、标准化,但常被错误实施。大多数错误都源于以下三条规则。
最长匹配优先,而非最前或最后。文件后面的 Disallow 可以覆盖前面 Allow,反之亦然,这完全取决于长度。 5xx 状态码表示完全禁止访问,这与直观的实现方式恰恰相反——一个运行不畅的网站应该从您这里获得更少的流量,而不是保持相同的流量。而且该文件必须至少每天刷新一次,因为网站可能会改变策略,而一周前的缓存副本已不符合规范。
请使用经过维护的解析器,而不是自己编写;确保您的 User-Agent 头中确实包含您期望匹配的令牌;并记录您跳过的内容,以便缺失的数据是经过决策的结果,而不是意外。
同时请牢记标准本身提出的警示。这些规则“并非一种访问授权形式”——遵守它们能使您成为网站运营商可以接受的爬虫,但这并不能解决其他问题,即条款允许什么,以及您可以如何处理收集到的数据。
