适用场景
站点已经积累了一批原创内容,日志里能看到 AI 训练爬虫频繁抓取,但既没有明确声明"能不能用",也没有收取费用的通道。这套方案解决三件事:把授权写成机器可读的声明、把抓取行为变成可计量的数字、让越权抓取能被拦截和追责。适合个人博客、内容站、文档站以及中小型 SaaS 的官网。
环境与前置条件
- Web 服务器:Nginx / Apache / Caddy 任一,能修改配置并重载;静态站托管在对象存储也可以,但边缘层规则要用托管商能力替代。
- 域名 DNS 托管在 Cloudflare 并开启代理(橙云),否则边缘的 AI 抓取控制与计费能力不生效;具体哪些能力需要付费套餐,以 Cloudflare 官方文档当前版本为准。
- 能写入网站根路径,
robots.txt与 RSL 授权文件都需要放在根目录对外可访问。 - 至少 30 天的访问日志,格式为 combined(含 User-Agent 字段),用于识别爬虫;日志建议单独分区,压缩后按每百万请求数十 MB 估算容量,保留 90 天左右。
- 一个可公开的许可说明页与联系邮箱,用于对方议价。
- 不需要 GPU;Web 服务器按常规配置即可,内存 1 GB 以上足够跑本教程涉及的规则。
分步骤部署
第 1 步:从日志里认出"谁在抓"
先按 User-Agent 统计。Nginx combined 日志按双引号切分后,第 6 个字段就是 User-Agent:
```bash
sudo awk -F'"' '{print $6}' /var/log/nginx/access.log \
| sort | uniq -c | sort -rn | head -30
```
再用已知的 AI 爬虫标识做一次聚合,看清各自抓了多少:
```bash
grep -Ei 'GPTBot|ClaudeBot|CCBot|AI 词典:Perplexity">PerplexityBot|Bytespider|meta-externalagent|Amazonbot|Diffbot|cohere-ai|ImagesiftBot|OAI-SearchBot' \
/var/log/nginx/access.log \
| awk -F'"' '{print $6}' | sort | uniq -c | sort -rn
```
注意两点:Google-Extended、Applebot-Extended 是 robots.txt 里的授权标识,不是真实 User-Agent,抓取时仍然显示为 Googlebot 和 Applebot,统计时不要混淆。各厂商的爬虫标识与官方 IP 段列表,以对应厂商官方文档当前版本为准。
UA 可以伪造,所以再按来源 IP 复核一遍:
```bash
grep -i 'GPTBot' /var/log/nginx/access.log | awk '{print $1}' \
| sort | uniq -c | sort -rn | head -20
```
对可疑 IP 做反向解析,与官方公布的网段比对:
```bash
for ip in $(grep -i 'GPTBot' /var/log/nginx/access.log | awk '{print $1}' | sort -u | head -20); do
printf '%s -> ' "$ip"; dig +short -x "$ip"
done
```
这一步的产出是一张表:爬虫名称、请求量、占带宽比例、是否命中官方网段。后面所有授权策略都以这张表为依据——量大且用于训练的,走"拦截或计费";只做检索并带来引流的,可以放行。
第 2 步:写 robots.txt,按爬虫分组授权
robots.txt 是声明层,没有强制力,但它是行业共识的入口,也是后续 RSL 引用的载体。按"搜索引擎放行、训练爬虫默认拒绝"的分组写法:
```
搜索引擎:放行,用于收录与引流
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
训练类爬虫:默认拒绝
User-agent: GPTBot
Disallow: /
User-agent: ClaudeBot
Disallow: /
User-agent: CCBot
Disallow: /
User-agent: Bytespider
Disallow: /
User-agent: meta-externalagent
Disallow: /
检索引用类:可放行,但保留署名要求
User-agent: OAI-SearchBot
Allow: /
User-agent: PerplexityBot
Allow: /
通用兜底
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /api/
Sitemap: https://example.com/sitemap.xml
```
再补一条内容信号声明,把"搜索可用、训练不可用"写成一行机器可读的标签(字段名以官方文档当前版本为准):
```
Content-Signal: search=yes, ai-input=yes, ai-train=no
```
页面上再叠一层元数据声明,覆盖单页粒度:
```html
<meta name="robots" content="noai, noimageai">
```
Nginx 也可以用响应头统一加:
```nginx
add_header X-Robots-Tag "noai, noimageai" always;
```
要提醒一点:Disallow 的值必须写路径,不能写完整 URL;通配符 * 和结尾 $ 并非所有爬虫都支持,能不用就不用。
第 3 步:生成机器可读的授权声明(RSL)
RSL 是一套把授权条款、用途限制和付费方式写成 XML 的开放规范,放在站点根目录,供爬虫自动解析。它的整体形状是"内容 → 许可 → 权限/支付"的嵌套,下面是结构示意:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<rsl>
<content url="https://example.com/">
<license url="https://example.com/ai-license.html">
<permission>ai-input</permission>
<prohibition>ai-train</prohibition>
<payment type="per-crawl" contact="licensing@example.com"/>
</license>
</content>
</rsl>
```
RSL 是较新的规范,元素名、命名空间、必填字段请以官方规范与官方校验器为准,不要凭记忆手写生产文件。落地时只要保证四件事写清楚:谁可以用、用来做什么、什么条件(含价格口径)下可以用、出问题找谁。价格不要在这里拍脑袋,先按成本倒推——一次抓取消耗的带宽、源站 CPU 与内容生产分摊成本,再加上你希望的内容溢价。
然后在 robots.txt 和页面里引用它:
```
License: https://example.com/rsl.xml
```
```html
<link rel="license" href="/rsl.xml">
```
第 4 步:在 Cloudflare 上把声明变成强制执行
1. 把域名接入 Cloudflare,确认 DNS 记录为代理状态,源站 IP 不直接暴露。
2. 打开面板里的 AI 抓取控制(AI Crawl Control),把识别到的 AI 爬虫逐个设置为"允许 / 阻止 / 计费"。这一步决定边缘是直接放行、返回拒绝,还是返回付费要求。
3. 用 WAF 自定义规则兜住漏网之鱼。表达式大致形如 (http.user_agent contains "GPTBot") or (http.user_agent contains "CCBot"),动作先设为 Log 观察几天,确认误伤为零再切 Block。
4. 开启按爬取计费后,边缘对未付费的抓取请求返回 HTTP 402,并附带价格与支付方式信息;该能力可能处于分阶段开放,面板里找不到开关通常说明尚未对你开放,以官方文档为准。
5. 顺手检查缓存规则:如果 AI 爬虫命中缓存,源站日志就统计不到真实抓取量,计费口径会失真。
第 5 步:源站兜底,自己也能返回 402 并计量
不依赖边缘能力时,用 Nginx 做一层识别与计量:
```nginx
map $http_user_agent $ai_bot {
default 0;
"~*GPTBot" 1;
"~*ClaudeBot" 1;
"~*CCBot" 1;
"~*Bytespider" 1;
}
log_format ai_pay '$remote_addr "$http_user_agent" $request_uri $status';
server {
access_log /var/log/nginx/ai_pay.log ai_pay;
location / {
if ($ai_bot) { return 402; }
try_files $uri $uri/ =404;
}
}
```
if 在 location 内的行为有边界情况,生产环境建议改用 map 加独立 server 块,或直接交给 WAF 处理。计量口径统一为"成功的 2xx 抓取次数",排除 304、402、403,避免重复计数。
验证部署是否成功
```bash
1. robots.txt 可访问且类型正确
curl -sI https://example.com/robots.txt | grep -Ei 'HTTP/|content-type'
2. 授权文件可访问且是合法 XML
curl -sI https://example.com/rsl.xml | grep -Ei 'HTTP/|content-type'
curl -s https://example.com/rsl.xml | xmllint --noout - && echo "XML OK"
3. 模拟训练爬虫
curl -A "Mozilla/5.0 (compatible; GPTBot/1.0)" -o /dev/null -s \
-w "%{http_code}\n" https://example.com/
4. 模拟普通访客
curl -o /dev/null -s -w "%{http_code}\n" https://example.com/
5. 确认请求确实进了计量日志
tail -5 /var/log/nginx/ai_pay.log
```
预期结果:前两条返回 200,rsl.xml 通过 XML 校验;模拟爬虫的请求返回 402(已开启计费)或 403(仅拦截);普通访客返回 200;计量日志里能看到刚才那次请求的 UA 与状态码。部署完成后观察 24 至 72 小时,真人流量曲线不应出现异常下跌。
常见报错与解决
报错一:改了 robots.txt,爬虫照抓不误
现象是日志里 AI 爬虫请求量没有下降。原因有两个:爬虫有自己的 robots.txt 缓存刷新周期;robots.txt 本身只是声明,没有强制力。解决办法是在边缘层强制拦截,并给 robots.txt 设置短缓存:
```bash
curl -sI https://example.com/robots.txt | grep -i cache-control
未设置时在 Nginx 中补:location = /robots.txt { add_header Cache-Control "max-age=3600"; }
sudo nginx -t && sudo systemctl reload nginx
```
报错二:robots.txt 规则被整段忽略
常见于分组之间漏了空行、User-agent 拼写错误,或把 Disallow 写成了完整 URL。先自查:
```bash
grep -n "Disallow: http" /var/log/../robots.txt
curl -s https://example.com/robots.txt
```
把绝对 URL 改回路径形式,用空行分隔不同分组,改完重新拉取确认。
报错三:拦截规则误伤了真人访客
原因是只按 User-Agent 匹配,浏览器插件或自建脚本的 UA 恰好命中关键词。做法是先用 WAF 的 Log 动作观察,或用日志抽样比对,确认误伤为零再切 Block;同时把判据从"仅 UA"改为"UA + 来源网段反查"。
```bash
sudo awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
```
报错四:rsl.xml 返回 404 或浏览器打开是一堆纯文本
文件没放在站点根路径,或服务器未声明 XML 的 MIME 类型。放到根目录后确认:
```bash
curl -sI https://example.com/rsl.xml | grep -i content-type
期望形如 application/xml 或 text/xml;Nginx 默认 mime.types 已包含
```
报错五:开了 Cloudflare 代理后,源站日志里的 IP 全是边缘节点地址
真实访客 IP 被代理覆盖,导致计量与反查全部失真。在 Nginx 中恢复真实 IP:
```nginx
set_real_ip_from <边缘网段>;
real_ip_header CF-Connecting-IP;
```
网段以 Cloudflare 官方文档当前版本为准,改完执行 nginx -t 并重载。
报错六:返回 402 后爬虫疯狂重试
缺少限速,导致日志和带宽被打爆。加限速并给出重试提示:
```nginx
limit_req_zone $binary_remote_addr zone=aibot:10m rate=10r/m;
limit_req zone=aibot burst=5 nodelay;
```
后续维护
备份方面,把 robots.txt、rsl.xml、Nginx 配置和 Cloudflare 规则导出文件一起放进 Git 仓库,每次改动留提交记录,便于回溯"某个时间点对外的授权条款是什么"。
升级方面,AI 爬虫的标识名单变化较快,建议每季度复核一次,新增标识的处理方式以各厂商官方文档与 Cloudflare 官方说明为准;RSL 规范仍在演进,字段调整前先在测试域名验证解析结果。
日志与监控方面,用 logrotate 做日志轮转并保留 90 天;重点监控四个指标:AI 爬虫请求占比、402/403 比例、被拒后的重试率、带宽成本趋势。阈值按自身基线设置,不要照搬别人的数字。
对账与追责方面,按月导出计量日志,与支付侧记录核对,差异超过预设比例时排查 UA 伪装和漏记。许可页面保持联系方式有效,收到议价或授权咨询时能快速响应——这正是"可声明、可计量、可追责"里最后一环的落点。
