首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >robots.txt 分开管 GPTBot 和 ClaudeBot:只拦训练抓取、放行搜索抓取,并验证真的生效

robots.txt 分开管 GPTBot 和 ClaudeBot:只拦训练抓取、放行搜索抓取,并验证真的生效

原创
作者头像
用户10345225
发布于 2026-11-05 11:59:12
发布于 2026-11-05 11:59:12
470
举报

为了让内容别被拿去训练,很多站点的 robots.txt 里会多出一段从别处抄来的规则。最常见的翻车是这样写的:

代码语言:txt
复制
User-agent: *
Disallow: /

这不是「只拦训练」,这是把搜索抓取一起关了。翻车方向反过来也一样常见:只写了 User-agent: GPTBot + Disallow: /,然后以为「AI 搜索里搜不到我们了」,其实搜索用途走的是另一条 token,那条规则管不着它。

robots.txt 是按产品 token 匹配的,一家厂商往往挂着好几条 token,每条管一件事。要把「拦训练、放搜索」做对,本质就是把这些 token 一条条分清楚,然后接受它只能表达意愿、不能强制执行。

token 的匹配规则先弄清楚

RFC 9309 写得很清楚:robots.txt 按 UA 里的产品 token 做大小写不敏感匹配;一个 group 由连续的 User-agent 行加紧跟其后的规则组成,这几行里的 token 共享同一组规则;匹配时取最具体的那条,Allow 和 Disallow 冲突时 Allow 优先。

由此而来的坑:

  • 连着写三行 User-agent 再写一条 Disallow,是三条 token 共用一条规则,不是三条各自独立。分厂商写策略时,每个 token 单独成组。
  • Disallow: / 对用途一视同仁。它表达的是「这条 token 别抓」,不是「这条 token 别拿去训练」。

常用 token 各自管什么

token

所属方

管的事

GPTBot

OpenAI

内容抓取与训练用途

OAI-SearchBot

OpenAI

搜索场景的抓取

ChatGPT-User

OpenAI

用户在对话里主动要求读取某个页面时触发

ClaudeBot

Anthropic

内容抓取

Claude-User

Anthropic

用户主动触发

Googlebot

Google

搜索抓取

Google-Extended

Google

不是爬虫,只声明 Googlebot 抓到的内容能不能用于 Gemini 的训练与 grounding

这张表别当永久事实用。厂商加 token、改用途都很常见,写完规则过一阵回来看一眼官方文档,比继续抄博客靠谱。Anthropic 那边与搜索相关的 agent 名称,以它自己的文档为准;拿不准的时候,先用日志确认真实来访的 UA 长什么样,再决定写哪条。

Google-Extended 有个容易搞混的点:它不会出现在访问日志里,因为它不是爬虫,只是一条声明。所以「日志里没看到 Google-Extended,是不是规则没生效」——它本来就不该出现。

把规则写出来

代码语言:txt
复制
# 默认:搜索引擎可以抓
User-agent: *
Allow: /

# OpenAI:训练抓取拒绝,搜索抓取放行
User-agent: GPTBot
Disallow: /

User-agent: OAI-SearchBot
Allow: /

User-agent: ChatGPT-User
Allow: /

# Anthropic:内容抓取拒绝,用户主动触发放行
User-agent: ClaudeBot
Disallow: /

User-agent: Claude-User
Allow: /

# Google:搜索照常,训练用途单独声明
User-agent: Googlebot
Allow: /

User-agent: Google-Extended
Disallow: /

给 GPTBot 单独 Disallow: / 之后,User-agent: * 里的 Allow: / 对它不再生效,更具体的 token 优先——这正是想要的效果。同理,后台路径、带参数的搜索结果页、带 token 的预览链接,把 Disallow 精确写在这些路径上,不要靠整站拦截。

robots.txt 本身别出问题

它只有在域名根、返回 200、Content-Type: text/plain 时才有效。常见故障:

  • 301/302 跳到别的域名,抓取方按「没有规则」处理。
  • 被 WAF 或 UA 黑名单先一步返回 403,抓取方读不到规则,文件里写什么都没用。
  • 文件带 UTF-8 BOM,第一行 User-agent 直接解析坏。
  • 被 CDN 缓存住,改完半小时还是旧的。

nginx 上给它单独一个 location,缓存别设太长:

代码语言:txt
复制
location = /robots.txt {
    default_type text/plain;
    add_header Cache-Control "public, max-age=3600";
    try_files $uri =404;
}

检查真实返回:

代码语言:bash
复制
SITE="https://你的域名"
curl -sS -D- -o /tmp/robots.txt "$SITE/robots.txt" | head -8
head -c 3 /tmp/robots.txt | xxd   # 期望 55 73 65(Use),不是 ef bb bf

再确认不同 UA 拿到的是同一份文件。有些 CDN 面板上的「AI 爬虫防护」开关会直接对这些 UA 返回 403,那就绕过了 robots.txt,你以为在表达意愿,实际上已经被挡在门外:

代码语言:bash
复制
for ua in "GPTBot/1.1" "ClaudeBot/1.0" "curl/8.5.0"; do
  printf '%-12s ' "$ua"
  curl -s -o /dev/null -w '%{http_code} %{size_download}\n' \
    -A "Mozilla/5.0 (compatible; $ua)" "$SITE/robots.txt"
done

三行都应该是 200,且 size 一致。

验证某条规则对特定 UA 是否生效

拦截动作是抓取方自己执行的,服务端测不出它会不会遵守,能测的是规则会被解析成什么。用标准库跑一遍,比肉眼核对可靠:

代码语言:python
复制
#!/usr/bin/env python3
# check_robots.py
import urllib.robotparser

SITE = "https://你的域名"
TARGET = "/blog/2026/some-post"
UAS = [
    "GPTBot", "OAI-SearchBot", "ChatGPT-User",
    "ClaudeBot", "Claude-User",
    "Googlebot", "Google-Extended",
]

rp = urllib.robotparser.RobotFileParser()
rp.set_url(f"{SITE}/robots.txt")
rp.read()

for ua in UAS:
    ok = rp.can_fetch(ua, f"{SITE}{TARGET}")
    print(f"{ua:16} {'ALLOW' if ok else 'DENY '}")

输出要和你写在文件里的意图一一对上。标准库实现不覆盖各家扩展,把它当粗筛;有争议时以真实抓取日志为准。

日志里看事实:

代码语言:bash
复制
sudo zcat -f /var/log/nginx/access.log* \
  | grep -Eio 'gptbot|oai-searchbot|chatgpt-user|claudebot|claude-user|perplexitybot|bytespider|googlebot' \
  | sort | uniq -c | sort -rn

想按爬虫分别看抓取量和被抓的路径,免费插件 AumCrawl 能把日志里出现过的 AI 爬虫分开统计,并按 token 放行或拦截:https://aumcreate.com/plugins/aumcrawl?utm_source=tencent&utm_medium=content&utm_campaign=tencent-robots-gptbot-claudebot-allow-deny 。它做的是服务端判断,和 robots.txt 是两码事,别互相替代。

改完多久生效

取决于对方下次来抓是什么时候,你这边能做的有限。已经排队或正在进行的抓取不会因为规则改了而撤回。自家 CDN 上的缓存要主动清,否则改了文件对方仍读到旧的。判断是否生效,看的是改完之后日志里那些 token 是否按新规则走,通常要等一个抓取周期。

这些做法的边界

robots.txt 是自律约定。愿意遵守的爬虫看它,不愿意遵守的直接无视,写什么都照抓。它适合表达「不希望内容被用于训练」这个意愿,不适合当安全边界。

只靠 UA 识别也不牢靠:UA 是客户端自己填的,伪装成浏览器或者伪装成 Googlebot 都只需要改一行配置。真要在服务端拦,得看 IP/ASN 和请求行为——请求频率、路径分布、是否只抓列表页不抓静态资源、HEAD 请求占比——而且一定会有误伤,得给搜索引擎和合作方留白名单。

还有个现实问题:同一家厂商既做搜索又做训练,token 怎么切分是它单方面定的,规则随时可能变,边界本来就不清晰。可操作的组合是——robots.txt 表明意愿,服务端限速与 UA 规则做实际控制,访问日志做事实核对;三样都留着,出问题时才有据可查。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • token 的匹配规则先弄清楚
  • 常用 token 各自管什么
  • 把规则写出来
  • robots.txt 本身别出问题
  • 验证某条规则对特定 UA 是否生效
  • 改完多久生效
  • 这些做法的边界
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档