跳到正文

AI 爬虫访问审计

速览要点

难度
进阶
预计耗时
首次完整审计约半天,之后每次复检约 1 小时
前置条件
AI 爬虫、robots.txt
审计目标
核实你决定放行的爬虫是否真的能抓取页面,以及你决定屏蔽的爬虫是否真的停止抓取。结论必须来自证据,不能只靠重读自己的 robots.txt
核查方法
比对意图、声明、实际、观测四种状态。每一条发现都来自相邻状态之间的不一致
代价最高的问题
声明与实际不一致。CDN、WAF 或机器人管理的默认设置,可能阻止 robots.txt 中明确放行的爬虫访问,而这类问题从文件本身根本看不出来
方法的适用边界
伪造用户代理字符串的探测只能证明放行,不能证明屏蔽。伪装成 GPTBot 的请求收到 403,最可能的解释是防伪造机制正常生效
判定基准
以书面策略为准,并非开放程度越高越好。按计划屏蔽训练爬虫不算发现;没有写下明确策略,才算问题

1. 这次审计要回答什么

一次 AI 爬虫访问审计需要核实两件事:你决定放行的爬虫是否真的能抓取页面;你决定屏蔽的爬虫是否真的停止抓取。两项判断都需要证据,重读一遍自己的 robots.txt 无法证明其中任何一项。

原因在于,robots.txt 只是一份声明,不能说明真实请求实际收到了什么。站点可以在文件中明确放行某个检索爬虫,实际请求却被 CDN 的机器人管理默认设置、WAF 托管规则、地域封锁或限速拦截在网络层,文件中不会留下任何痕迹。这类问题代价最高,因为排查通常从这份文件开始,而问题本身恰好无法从文件中发现。

反过来也同样需要证据。写了 Disallow 不等于对方停止抓取:RFC 9309 写明其规则「并不构成一种访问授权」,是否遵守取决于厂商公布的政策,并非技术保证。只有日志能说明谁真正到访过,而且必须先核实来访者身份。

审计最终会形成一份不一致项清单:每条发现都要说明哪两种状态互相矛盾、证据是什么、严重程度如何,以及应该在哪一层修复(内容层、配置层或网络层)。下文从意图、声明、实际、观测四种状态检查访问情况。这是 GEO Wiki 为此类比对采用的组织方式,并非行业通行的审计口径;能够指导修复的并不是四种状态本身,而是相邻状态之间的不一致。

2. 开始审计前:范围、程序清单、意图策略、取证时间范围

审计前需要确定四项前提,它们决定后续每条发现应如何解释。

审计前提需要明确的内容判定要点
范围每个主机 × 每种协议 × 每个 CDN 区域robots.txt 是按主机生效的:主域、wwwdocs.blog. 各自都需要一份。漏审子域是最常见的覆盖缺口
程序清单类别选择,不以知名度为准训练、检索、用户触发这三类各至少取一个代表,再加入你的受众实际使用的引擎。分类依据见 AI 爬虫
意图策略是否已经写成明确策略缺少书面策略,就无法判定其他问题;策略缺失本身就是第一条发现(见 §8)
取证时间范围日志保留期与分析数据保留期如果保留期短于爬虫的回访周期,观测结果就不足以支持结论。审计开始前必须确认

每条发现都应以既定意图为判断基准,而不是以开放程度高低为准。对于有意拒绝训练爬虫的站点,GPTBot 被 Disallow 不构成发现,因为策略正在按预期生效;如果同一策略下的检索爬虫被 WAF 拦截,则应记录为发现,因为策略中并没有这项决定。

适合重新审计的时机:CDN 或 WAF 变更后、站点迁移后、新增防护措施后、更换 CMS 或插件后、新爬虫上线时,以及厂商默认策略的变更日(§7 列出了一项带日期的变更)。

3. 访问的四种状态

四种状态,各有各的证据来源。

状态需要回答的问题证据来源
意图(intended)你按类别决定了什么?一份书面策略(没有则构成第一条发现)
声明(declared)站点在每个主机、每种协议下对外声明了什么?实地取回 /robots.txtX-Robots-Tag、robots meta
实际(effective)一个真实请求实际收到了什么?合成探测:状态码、响应体积、正文哈希
观测(observed)谁真正到访过,身份能否核实?访问日志或边缘日志,加上 IP 段比对与反向解析

单独查看任何一种状态,都不足以判断问题。能够指导修复的发现来自相邻两种状态之间的不一致,共分为三类:

不一致项常见根因修复位置
意图 ≠ 声明CDN 在边缘注入的 robots.txt 覆盖了站点文件;CMS 或插件的默认值;测试环境配置被误用于生产环境;子域没有自己的文件配置层
声明 ≠ 实际机器人管理、WAF 托管规则、地域或 ASN 封锁、限速、人机校验拦截页网络层,最容易漏查的一类
实际 ≠ 观测没有到访记录(应排查页面是否被发现以及抓取优先级,而不是屏蔽);或者写了 Disallow 后仍有到访(对方不遵守,或有人冒用身份)分发层或安全层

按声明、实际、观测的顺序核查,因为每一步的验证成本都高于前一步;许多问题用前面的低成本证据就能定位,无需继续投入更高成本。

4. 第一步:核查声明层

实际获取文件,不能只在浏览器中查看;范围内的每个主机都要检查:

for h in example.com www.example.com docs.example.com blog.example.com; do
  printf '%-24s ' "$h"
  curl -sS -o "robots-$h.txt" -w '%{http_code} %{size_download}B\n' "https://$h/robots.txt"
done
shasum robots-*.txt

这一步能得出两个判断。4xx 意味着这个主机没有声明任何规则,遵守协议的爬虫此时可以抓取任意路径。哈希一致,说明全站确实采用同一份策略;哈希不一致,说明策略按主机有所区分,这种差异应当符合既定意图。分组合并、路径优先级等解析规则,遵循 robots.txt 中的通用说明。

检查边缘是否覆盖了文件。CDN 可以在边缘注入或替换 robots.txt,因此站点对外提供的文件可能与仓库中的文件不同,即使仓库文件本身从未改动。判断方法是比对内容:将边缘返回的文件与仓库文件逐字节核对。这比查看任何配置面板都可靠,因为它直接验证站点实际对外提供的内容,而不是配置者的意图。

页面级指令也属于这一层X-Robots-Tag 响应头和 robots meta 标签同样是对外声明,但它们管的是索引和展示,不是抓取:

curl -sSI "https://example.com/pricing" | grep -i 'x-robots-tag'

这个区别对后续分类很重要。Google 的文档写明,如果一个页面在 robots.txt 中被屏蔽,「Googlebot 将永远不会抓取该页面,也就永远读不到页面上的任何 meta 标签」(见 robots meta 标签规范)。抓取屏蔽与索引屏蔽的表现和修复方法都不同,记录时必须明确区分,以免在 §8 中误判。

llms.txt 既不授予访问权限,也不拒绝任何访问,因此不会构成此次审计中的发现。它是否存在、内容是否准确,见 llms.txt 部署

5. 第二步:探测实际层

对同一个网址发出两次请求:一次作为基线,一次伪装成爬虫。比较以下三项,不能只看其中一项:

URL="https://example.com/pricing"
UA_BROWSER="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
UA_BOT="PerplexityBot"   # 多数 UA 规则只匹配这个名字本身,够用了

curl -sS -A "$UA_BROWSER" -o base.html -w 'baseline %{http_code} %{size_download}B\n' "$URL"
curl -sS -A "$UA_BOT"     -o bot.html  -w 'bot      %{http_code} %{size_download}B\n' "$URL"
shasum base.html bot.html

只看状态码不够,因此命令还会比较响应体积和正文哈希:人机校验页和软屏蔽都可能返回 200。各家公布的完整用户代理字符串包含会变动的版本号,各爬虫的详细记录见 GPTBotClaudeBotPerplexityBot

不要只测试一个网址。应当按照矩阵取样:首页、一个核心内容模板、一个带分页或筛选的路径,以及一个受限路径。每个样本都要完整记录五项信息:网址模板、爬虫令牌、状态码、体积、判定。

信号判定
403401硬屏蔽
429,或持续请求一段时间后开始失败限速
200,但响应体积远小于基线人机校验或拦截页
换一个出口地区结果就不同地域或 ASN 封锁
200,体积也合理,但初始 HTML 里没有正文空壳页,详见下文

页面返回 200,正文却因依赖客户端渲染而不在响应中,应记录为空壳页。按照完整 GEO 审计的分层,这属于第 2 层问题,修复方法见面向 AI 爬虫的 SSR。正文体积本就是本步骤的比对项,因此可以同时发现这类问题。

方法的适用边界:伪造用户代理字符串的探测只能证明放行,不能证明屏蔽。厂商爬虫通常根据公布的 IP 段或反向解析结果放行,而不是只看用户代理字符串。Cloudflare 的已核验程序机制就是一例:程序必须通过 Web Bot Auth 密码学签名、公布 IP 清单或反向解析三种方式中的一种证明真实身份,同时不得有滥用行为(见 Verified bots)。因此,伪装成 GPTBot 的请求收到 403,最可能的解释是防伪造机制正常生效,而不是真实爬虫被屏蔽。这个推断只能用于验证放行:伪造令牌拿到 200,真实爬虫通常也能通过。确认是否屏蔽,需要查看 §6 所述的日志证据。

前两步可以一次完成:免费的 AI 爬虫访问检测工具会逐一评估 robots.txt 中针对 26 个 AI 令牌的规则,并以浏览器请求为基线,在边缘执行差分探测;每条判定都会引用最终生效的规则原文。工具采用的正是上述单向推断,§6 的日志核实仍需人工完成。

6. 第三步:核实观测层

许多站点无法获取源站访问日志,而缺少日志的站点往往最需要核实观测情况。

日志来源可提供的信息使用方式
源站访问日志(nginx、Apache)来访者、到访时间、响应状态码和抓取网址直接 grep
CDN 分析或日志导出边缘侧的真实情况,包括尚未到达源站就被拦截的请求平台分析面板或日志导出
不提供访问日志的托管平台信息有限,只能使用平台自带的机器人分析如果源站日志和边缘数据都缺失,应将其记录为一条发现,并先补齐观测能力

这里有一个硬性限制:源站日志看不到被 CDN 在边缘拦截的请求。§3 中声明与实际不一致的那类问题,只会在边缘数据中留下痕迹,因此只检查源站日志的站点很容易长期漏查。

日志保留期也很容易造成误判,而且通常比预期短得多。Vercel 的文档写明,运行时日志在 Hobby 套餐保留 1 小时、Pro 套餐保留 1 天(开通 Observability Plus 后为 30 天);静态请求只有命中缓存时才会进入运行时日志,完整的静态请求日志需要开启日志导出(见 Vercel 运行时日志)。如果爬虫按月回访,一天的日志无法反映其到访情况。

按令牌汇总到访情况:

# 哪些 AI 令牌来过,来自哪些 IP,拿到了什么?
# 按自己的日志格式调整 awk 的列号($1 为客户端 IP,$9 为状态码)。
grep -iE 'GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-SearchBot|Claude-User|PerplexityBot|Perplexity-User|Googlebot|Bingbot' access.log \
  | awk '{print $1, $9}' | sort | uniq -c | sort -rn | head -40

这里应查看每个令牌的状态码分布,而不是到访总次数。如果某个令牌持续到访,响应却几乎全为 403,就可以确认存在屏蔽;如果响应为 200,则可确认放行,但前提是请求身份已经核验。

确认身份需要两步。先将来源 IP 与厂商公布的清单比对,再做前向确认反向解析(forward-confirmed reverse DNS)。Google 文档规定的顺序是:先对来访 IP 做反向解析,再将得到的主机名正向解析,确认结果仍是同一个地址(见 Verify Google requests)。

host 203.0.113.10          # → 反向解析得到主机名
host crawl-203-0-113-10.googlebot.com   # → 必须解回 203.0.113.10

各家公布的清单地址,核对时间为 2026 年 7 月 29 日:

厂商令牌公布的 IP 清单说明
OpenAIGPTBot、OAI-SearchBot、ChatGPT-Usergptbot.jsonsearchbot.jsonchatgpt-user.json逐程序分开的文件;GPTBot 与 OAI-SearchBot 之间有共用网段
AnthropicClaudeBot、Claude-SearchBot、Claude-Userclaude.com/crawling/bots.json合并成一份文件;Anthropic 写明,来源 IP 只要出现在这份清单上,「即表明该爬虫来自 Anthropic」
PerplexityPerplexityBot、Perplexity-Userperplexitybot.jsonperplexity-user.json文档建议用户代理字符串匹配与 IP 核验两者并用
GoogleGooglebot、Google-Extendedcommon-crawlers.json,另有特例爬虫和用户触发取页各一份这些文件已于 2026 年 3 月迁至 /crawling/ipranges/;反向解析结果落在 googlebot.comgoogle.com 的主机名上
MicrosoftBingbot未公布只能靠反向解析到 search.msn.com 下的主机名,或使用 Verify Bingbot 工具

解读这张表时还需注意两点。Google-Extended 是一个没有对应爬虫的控制令牌,因此不会产生任何日志记录,观测状态无法提供证据,只能核查站点的对外声明。公布的 IP 清单则用于确认入站请求身份,并非长期有效的屏蔽名单。Anthropic 明确指出:「屏蔽 Anthropic 程序所使用的 IP 地址这类替代做法,可能无法正确生效,也不能持续保证退出」,因为它的爬虫运行在公有云地址上(见 Anthropic 爬虫文档)。

如何解读日志中的空白。没有记录不等于爬虫被屏蔽。它可能尚未发现这些页面,可能抓取优先级很低,可能回访周期长于日志保留期,也可能根本不使用自己的爬虫处理这类页面。应结合 §5 的结果判断:实际请求正常、日志中却没有记录,说明应排查页面是否被发现以及抓取优先级。解决方法是加强更新通知和收录覆盖信号,见 Sitemap 与 IndexNow,这与页面能否访问无关。

有一类爬虫不适用这套方法。用户触发的取页只在有人询问某个具体网址时发生,数量少且不规律,因此不能根据到访次数验证放行或屏蔽策略。关于 robots.txt 是否约束这类爬虫,见官方说明 ChatGPT-User

7. 基础设施如何改变访问结果

决定访问结果的因素,越来越多地位于站点文件之外。

影响访问结果的因素受影响的状态容易漏查的原因
CDN 机器人管理的默认设置声明 → 实际按套餐档位生效,可能与站点配置无关
边缘注入的 robots.txt意图 → 声明仓库文件可能与站点实际对外提供的文件不同
WAF 托管规则集声明 → 实际按厂商的时间表更新,不由站点决定
按次计费与协商类控制声明 → 实际可能返回 402 Payment Required,表面上不同于常见的屏蔽响应
平台级默认策略变更声明 → 实际到指定日期自动生效,站点配置无需发生任何变动

不同套餐档位提供的识别能力不同,这会直接影响可识别和拦截的爬虫范围。Cloudflare 写明「在免费套餐下,AI Crawl Control 依据用户代理字符串识别 AI 爬虫」,更全面的机器人管理识别需要付费套餐,屏蔽时可以返回 403402(见 Manage AI crawlers)。按用户代理字符串识别与按身份识别的失效方式完全不同,解释 §5 中的 403 时必须先确认实际采用哪种方式。

有一项带日期的变更需要提前纳入审计安排。Cloudflare 说明,从 2026 年 9 月 15 日起,「在展示广告的页面上,训练类和 agent 类将默认屏蔽,搜索类仍然默认放行」。这套默认值适用于新接入的域名,已有客户可以提前设定自己的偏好(见 Cloudflare)。这项变更会直接影响审计:站点文件没有任何改动,实际访问结果却可能发生变化。

现有证据表明,访问结果已不再只由一份文本文件决定,网络层和合同约定的作用正在增加。下一步发展方向是用密码学验证程序身份:IETF 已经成立 Web Bot Auth 工作组,draft-meunier-web-bot-auth-architecture 提出让自动化客户端「对发出的请求做密码学签名,使 HTTP 服务器能够可靠地核验其身份」。这份草案目前由个人提交,被列为工作组可能采纳的输入文档之一,尚未成为标准,因此现在还不能将其视为可审计的控制手段。对本次审计而言,声明状态的证据价值正在下降,实际状态和观测状态的证据价值正在上升。

8. 汇总:给发现分类并排序

每条发现都包含三部分:哪两种状态不一致、证据是什么、应该在哪一层修复。严重级别沿用完整 GEO 审计的分级,但判定依据是受影响的爬虫类别,而不是层号。

发现严重级别判定依据
检索爬虫在网络层被拦截,与意图相反阻断级立刻失去被引用的资格,而且无法从文件中发现
检索爬虫在 robots.txt 里被 Disallow,与意图相反阻断级代价相同,但修复成本最低
缺少书面的意图策略阻断级其余每一条发现都无从判定
子域或协议没有自己的 robots.txt,行为与主域不一致重大级容易被忽略的覆盖缺口
返回 200,正文却是空壳重大级(转第 2 层处理)可以抓取,但无法读取正文
限速导致抓取深度被截断重大级抓取覆盖不完整
训练爬虫按计划被屏蔽不算发现策略正在按预期生效
到访记录与声明的策略相矛盾次要到重大级,取决于规模需要修复的是网络层,而不是文件层

严重级别不等于修复优先级。为 WAF 增加一条白名单,与将整个站点迁出客户端渲染架构,工作量相差很大。制定行动计划前,应按照影响大小、证据可信度和修复难度重新排序;完整 GEO 审计对全部六层采用的也是这套排序方法。

9. 结论可靠性与常见陷阱

  • 只在自己的网络里做探测。办公室 IP 常常本来就在白名单里,结论无法推广到公网。
  • 伪造的用户代理字符串收到 403,就当成屏蔽证据。这项误判的代价最高,见 §5。
  • 只比状态码。这样会漏检返回 200 的人机校验页和空壳页。
  • 只查源站日志。被边缘拦截的请求根本到不了源站,因此无法发现这类问题。
  • 只审主域robots.txt 按主机生效,每个子域都要单独查。
  • 日志保留期短于回访周期。此时的观测结果不足以支持任何结论。
  • 只抽一个网址模板。这样无法发现按路径生效的规则,以及不同模板之间的差异。
  • 刚改完 robots.txt 就去复检。策略不会立即生效,各家公布的时长不同,而且通常只说明搜索类爬虫:OpenAI 公布的数字就只针对搜索结果,见 GPTBot
  • 把没有被引用当成访问问题。是否获得引用需要通过引用追踪衡量,与访问问题不同。
  • 只审一次。即使站点没有更改配置,厂商默认设置和托管规则集也可能改变结果(见 §7)。

10. 报告交付物与复检节奏

每次都要交付的内容:

  • 报告头:审计日期、范围内的主机清单、程序清单、本次对照的意图策略版本,以及取证时间范围。
  • 四种状态的取证记录:记录每个主机的四种状态,并附上命令输出或日志片段。
  • 不一致项清单:每条写明哪两种状态矛盾,附严重级别和需要修复的位置。
  • 按优先级排序的修复项:§8 中重新排序后的清单。
  • 与上次的差异:说明本次结果相较上次发生了哪些变化,以及变化来自站点操作还是厂商调整。

复检频率应根据成本分别设定。声明状态和实际状态的核查成本较低,适合加入定期任务,以便及时发现厂商默认设置或托管规则集的变化。观测状态应与完整审计同步核查:按季度进行,或在 §2 所列条件触发时进行。

复核日期应与访问指令一起写入策略。外部限制一直在变化:一项覆盖 14000 个域名的纵向研究发现,仅 2023 到 2024 一年之间,C4 语料中就有超过 5% 的 token 被完全限制使用;在其中维护最活跃的来源里,这一比例超过 28%(见 Longpre 等,2024)。策略制定后如果从不复核,很快就会与实际情况脱节。

11. 相关条目

参考资料

Primary

Secondary

常见问题

为什么读一遍自己的 robots.txt 还不够?
因为 robots.txt 只是一份声明,不能说明真实请求实际收到了什么。文件可能明确放行某个检索爬虫,CDN 的机器人管理默认设置、WAF 托管规则、地域封锁或限速却在网络层将其拦截,而这些情况在文件中完全看不到。反过来也一样:写了 Disallow 不等于对方停止抓取,因为遵守该指令是厂商公布的政策,并非技术保证。只有探测结果和日志才能说明实际发生了什么。
我把用户代理字符串设为 GPTBot,再用 curl 请求自己的站点,能测出它是否被屏蔽吗?
这种方法只能验证放行,不能确认屏蔽。伪装成 GPTBot 的请求拿到 200,真实爬虫通常也能获得相同响应;如果拿到 403,最可能的解释却是防伪造机制正常生效。厂商爬虫通常根据公布的 IP 段或反向解析结果放行,而不是只看用户代理字符串,因此伪造的字符串会被视为冒用。要确认是否屏蔽,必须查看日志,并先核实请求身份。
如果我的托管平台不提供访问日志怎么办?
缺少观测能力本身就是第一条发现,不能因此省略核查。不少无服务器(serverless)平台只提供函数级日志,而且保留期很短:Vercel 文档写明,Hobby 套餐保留 1 小时,Pro 套餐保留 1 天;静态请求只有命中缓存时才会进入运行时日志,完整的静态请求日志需要开启日志导出。边缘日志或 CDN 分析可以替代源站日志;如果两者都没有,应先补齐观测能力,再判断哪些爬虫到访过。
某个爬虫在日志里一次都没出现,是被屏蔽了吗?
不一定。没有记录并不能证明爬虫被屏蔽。它可能尚未发现你的页面,可能抓取优先级很低,可能回访周期长于日志保留期,也可能根本不使用自己的爬虫处理这类页面。应结合探测结果判断:如果实际请求正常返回 200,日志中却没有到访记录,就应排查页面是否被发现以及抓取优先级,而不是访问能力。
按 IP 屏蔽爬虫管用吗?
作为强制屏蔽手段并不可靠,厂商也明确说明了这一点。Anthropic 写明「屏蔽 Anthropic 程序所使用的 IP 地址这类替代做法,可能无法正确生效,也不能持续保证退出」,因为它的爬虫运行在公有云地址上。公布的 IP 清单适合用来确认入站请求的身份,本次审计也只将其用于身份核验;它不适合作为长期有效的屏蔽名单。

相关指南与百科

参考来源

一手来源

  1. RFC 9309: Robots Exclusion Protocol · IETF · 2022-09-01
  2. Verify requests from Google crawlers and fetchers · Google Search Central
  3. Google crawler IP ranges — common-crawlers.json · Google
  4. New location for the Google crawlers' IP range files · Google Search Central
  5. Robots meta tag, data-nosnippet, and X-Robots-Tag specifications · Google Search Central
  6. Does Anthropic crawl data from the web, and how can site owners block the crawler? · Anthropic
  7. Anthropic crawler IP list (bots.json) · Anthropic
  8. Perplexity Crawlers (PerplexityBot / Perplexity-User) · Perplexity AI
  9. Overview of OpenAI Crawlers · OpenAI
  10. How to verify Bingbot · Microsoft Bing
  11. Verify Bingbot tool · Microsoft Bing
  12. Verified bots · Cloudflare
  13. Manage AI crawlers — AI Crawl Control · Cloudflare
  14. Your site, your rules: new AI traffic options for all customers · Cloudflare · 2026-07-01
  15. Runtime Logs — retention limits by plan · Vercel
  16. HTTP Message Signatures for automated traffic: Architecture (draft-meunier-web-bot-auth-architecture) · IETF (Internet-Draft) · 2026-03-02

二手来源

  1. Consent in Crisis: The Rapid Decline of the AI Data Commons · Longpre et al. (arXiv / NeurIPS D&B)
  2. Anthropic clarifies how Claude bots crawl sites and how to block them · Search Engine Land
  3. Perplexity is using stealth, undeclared crawlers to evade website no-crawl directives · Cloudflare
首次发布: 2026-07-29 最近更新: 2026-08-18 作者: Ray Yang 主题: 实践