Cloudflare 这次默认规则更新,把一个长期模糊的问题摆到台面上:同一个爬虫既做搜索索引,又拿页面去训练模型或驱动 AI 代理,还能不能被网站当成“正常搜索流量”放行?按新规,AI 厂商需要在 9 月 15 日前拆分搜索爬虫、模型训练爬虫和 AI 代理专用爬虫。未完成区分的混合爬虫访问带广告页面时,会被系统自动拦截。
这不是一个只影响大站的变更。摘要里提到,新入驻平台客户、老用户新建站点、全部免费用户网站都会统一生效。对站长和后端团队来说,重点不是“要不要反 AI”,而是要把爬虫策略从一行 robots.txt,升级成可审计、可回滚、可解释的访问控制。
混合爬虫的问题:身份和用途绑在一起
传统搜索爬虫的交换关系相对清楚:抓取页面,建立索引,给站点带来搜索曝光。AI 训练爬虫和 AI 代理爬虫的目标不同:前者可能批量抽取内容用于模型训练,后者可能代表用户实时读取页面、总结内容、执行任务。
混合爬虫把这些用途塞进同一个 User-Agent、同一组 IP 或同一套验证身份里,网站管理员就很难做细粒度决策:
- 允许搜索索引,但不允许训练模型。
- 允许 AI 代理访问公开文档,但不允许抓取广告变现页面。
- 允许低频访问,但不接受批量抓取。
- 对登录后内容、付费内容、广告页面采用不同策略。
Cloudflare 的新规本质上是在推动“用途可区分”。爬虫厂商如果继续使用混合身份,站点侧就只能粗暴处理:要么全放,要么全拦。现在默认规则会在特定场景下直接偏向拦截。
哪些网站会先感受到变化
摘要给出的覆盖面很大:新客户、老用户新建站点、免费用户网站都会进入默认规则范围。也就是说,一些过去没有主动配置 Bot 管理或 WAF 规则的网站,也可能突然观察到 AI 相关爬虫命中拦截。
最容易出现告警或业务影响的地方通常有三类:
- 内容站:文章页、商品页、论坛帖、问答页被高频抓取。
- 带广告页面:新规明确提到混合爬虫访问带广告页面会被自动拦截。
- 依赖搜索曝光的网站:如果某些搜索爬虫身份被混合使用,站长需要确认它是否被误伤。
这里的关键动作是观测。不要只看“总流量降了没有”,要按 User-Agent、路径、状态码、Cloudflare 安全事件分组,看哪些爬虫从 2xx 变成了 403、429 或 challenge。
可以这样实践:先建立爬虫访问审计
下面这个小脚本假设你有一份 Web 访问日志,格式至少包含 IP、时间、方法、路径、状态码和 User-Agent。它不会替代 Cloudflare 日志,但可以帮助你在本地先找出高频爬虫和可疑混合身份。
把 access.log 换成你的日志文件路径即可运行。
python3 - <<'PY'
import re
from collections import Counter, defaultdict
log_file = 'access.log'
ua_counter = Counter()
status_by_ua = defaultdict(Counter)
path_by_ua = defaultdict(Counter)
# 适配常见 combined log:IP - - [time] "GET /path HTTP/1.1" 200 size "ref" "ua"
pattern = re.compile(r'"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH)\s+([^\s]+)\s+HTTP/[^"]+"\s+(\d{3})\s+\S+\s+"[^"]*"\s+"([^"]*)"')
with open(log_file, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
m = pattern.search(line)
if not m:
continue
method, path, status, ua = m.groups()
ua = ua or '-'
ua_counter[ua] += 1
status_by_ua[ua][status] += 1
path_by_ua[ua][path.split('?')[0]] += 1
keywords = ('bot', 'crawler', 'spider', 'gpt', 'ai', 'claude', 'perplexity', 'search')
for ua, count in ua_counter.most_common(30):
if any(k in ua.lower() for k in keywords):
print('\nUA:', ua)
print('requests:', count)
print('statuses:', dict(status_by_ua[ua].most_common()))
print('top_paths:', path_by_ua[ua].most_common(5))
PY
这个脚本的价值不在于“识别所有 AI 爬虫”,而是给你一份排查清单:哪些 User-Agent 命中了广告页,哪些路径被重复扫,哪些状态码在规则更新后发生了变化。
可以这样实践:把策略拆成搜索、训练、代理三类
如果你的站点需要主动表达访问边界,可以从 robots.txt 开始,但不要只依赖它。robots.txt 是声明,不是强制访问控制;真正的拦截还需要 WAF、Bot 管理、应用层限流或鉴权配合。
一个偏保守的 robots.txt 可以这样写,具体 User-Agent 名称需要按你实际观察到的爬虫替换:
# 允许传统搜索引擎抓取公开页面
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
# 示例:限制模型训练或不明用途 AI 爬虫
# 将 ExampleAI-TrainingBot 替换为你日志中看到的真实 User-Agent
User-agent: ExampleAI-TrainingBot
Disallow: /
# 示例:限制 AI 代理访问广告、结算、登录等敏感路径
User-agent: ExampleAI-AgentBot
Disallow: /ads/
Disallow: /checkout/
Disallow: /login/
# 对未知爬虫保持基本边界
User-agent: *
Disallow: /admin/
Disallow: /account/
如果你使用 Cloudflare,可以在控制台里把规则写成更清晰的分层策略。下面是一个可改造的 Cloudflare Rulesets API 示例,用于创建一条基于 User-Agent 和路径的自定义拦截规则。运行前需要替换 CLOUDFLARE_API_TOKEN、ZONE_ID、User-Agent 关键字和路径。
export CLOUDFLARE_API_TOKEN='replace-me'
export ZONE_ID='replace-me'
curl -sS -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/rulesets" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"name": "crawler-purpose-policy",
"kind": "zone",
"phase": "http_request_firewall_custom",
"rules": [
{
"action": "block",
"expression": "(http.user_agent contains \"ExampleAI\" and http.request.uri.path contains \"/ads/\")",
"description": "Block unclear AI crawler access to ad pages",
"enabled": true
}
]
}'
生产环境里建议先把动作设成日志或挑战,而不是直接全站 block。等你确认不会影响搜索索引、合作伙伴抓取和内部监控后,再逐步收紧。
站长真正要决定的不是“放”还是“拦”
这次规则更新给网站侧带来的实际工作,是把爬虫治理从情绪化选择变成工程化策略。可以按下面的清单推进:
- 列出你愿意放行的搜索爬虫,并确认它们的 User-Agent、验证方式和访问路径。
- 单独定义模型训练爬虫策略:允许、拒绝、限速,还是只开放特定目录。
- 单独定义 AI 代理策略:公开文档页、帮助中心可能可放行;登录、结算、广告、账号页面应更谨慎。
- 观察 Cloudflare 安全事件和源站日志,按 User-Agent、路径、状态码做对比。
- 对误伤风险高的规则先使用日志模式或小范围灰度。
- 把例外规则写入变更记录,避免半年后没人知道为什么某个爬虫被放行。
Cloudflare 的默认规则会替你做一部分拦截,但它不能替你定义内容授权、商业边界和搜索策略。9 月 15 日这个期限更像一个倒计时:AI 厂商要拆清身份,网站也该拆清自己的访问政策。混合爬虫越晚拆,站点侧越倾向于用粗粒度规则处理它。这个方向已经很明确。