PerplexityBot 三天抓了全站,GPTBot 只来了一次:AI 爬虫日志行为差异排查记

2026-09-27 01:19:28 0 次浏览
GEOAI爬虫Nginx日志分析robots.txt

一个来自本地连锁企业的问题

场景是这样的:一家本地连锁服务企业,门店分布在一个城市及周边区县,官网内容不算多,两百多个页面。运营在 Perplexity 上搜自家门店的服务词,发现回答里引用了官网;换 ChatGPT 搜索问同样的问题,回答里却完全没有这个站。团队的第一反应是「是不是被屏蔽了」,第二反应是来找我这个管运维的朋友帮忙看。

AI 爬虫日志行为差异分析示意图

我们的判断是:与其猜,不如直接看日志。Web 服务器日志里躺着一手证据——各家 AI 爬虫到底来没来、来了多少次、抓了什么、抓完走了没有。这篇把这两周的排查过程、观测数据和踩过的坑整理出来,操作部分全部可复现。

核心背景:AI 搜索引用一个网站的前提是它能抓到、且认为值得抓,日志是验证这件事最可靠的一手入口。

准备工作:先把日志按 AI 爬虫 UA 拆开

User-Agent(UA)是 HTTP 请求头里声明客户端身份的字段,Nginx 的 combined 日志格式会把它记在双引号包裹的字段里。主流 AI 爬虫都有可识别的 UA 标识:OpenAI 的 GPTBot、Anthropic 的 ClaudeBot、Perplexity 的 PerplexityBot、Google 的 Google-Extended(控制 Gemini 训练数据来源的开关型 UA)、字节跳动的 Bytespider。

分析窗口取 2026-09-07 到 2026-09-20 两周,环境是单台 Nginx 1.24,日志默认 combined 格式。整个分析可以抽象成一条流水线,先看全貌:

flowchart LR
    A[Nginx 原始 access.log] --> B[按时间窗切片]
    B --> C[UA 正则初筛 AI 爬虫]
    C --> D{UA 可信?}
    D -- 可信 --> E[正向 DNS 验证]
    D -- 存疑 --> F[标记为伪造或扫描器]
    E --> G[统计请求数/路径分布/状态码]
    G --> H[输出行为画像与优化清单]
    F --> H

落地的统计命令如下,可以直接抄走改路径用:

# 前置条件:Nginx 1.24,combined 日志格式,access.log 在 /var/log/nginx/ 下
# 时间窗:2026-09-07 至 2026-09-20,按日期切好的日志文件合并为 access.log
# 第一步:统计各 AI 爬虫 UA 的两周请求数,UA 在双引号包裹的字段里
grep -hE "GPTBot|ClaudeBot|PerplexityBot|Google-Extended|Bytespider" access.log \
  | awk -F'"' '{print $6}' | sort | uniq -c | sort -rn
# 第二步:拆 PerplexityBot 的抓取路径分布 Top 20,看它到底在抓什么
grep "PerplexityBot" access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20
# 第三步:状态码分布,404 占比过高说明 sitemap 或外链里存在死链
grep "GPTBot" access.log | awk '{print $9}' | sort | uniq -c
# 第四步:按天统计抓取趋势,判断是匀速爬还是突发式抓取
awk '/PerplexityBot/ {print $4}' access.log | cut -d: -f1 | sort | uniq -c

跑完第一轮统计,结论比预想刺激得多:两周里 PerplexityBot 打了三千多次,几乎把全站能抓的都抓了一遍;GPTBot 只出现了 1 次,抓的还是 robots.txt。差别大到不像同一个互联网上的爬虫。

一手观测数据:单站两周的 AI 爬虫行为画像

先交代口径:以下数据来自单台服务器、单一站点,时间窗 2026-09-07 至 2026-09-20,样本量有限,只代表这一类内容结构不复杂的本地服务站的情形,不要直接外推到资讯站或电商站。

爬虫 UA 两周请求数 最深抓取层级 404 占比 robots.txt 请求次数 内容更新后复抓延迟
PerplexityBot 3,471 6 级(详情页与参数页) 2.1% 2 24 小时内
Bytespider 9,860 9 级 6.8% 1 无明显规律
ClaudeBot 604 4 级 1.2% 2 约 3 天
GPTBot 1 1 级(仅 robots.txt) 0% 1 一周内未复抓
Google-Extended 0 无 无 0 无

几个数字值得展开说一下。

PerplexityBot 的抓取路径高度集中在「服务详情页」和「门店地址页」两类,Top 20 路径占了总请求的 61%。它的抓取有明显节奏:不是匀速,而是每隔几小时来一波突发,一波几十个请求集中打完。我们当时猜背后是查询驱动的按需抓取,这个猜测和后面的原理分析能对上。

Bytespider 是另一种画风:请求量巨大,路径广度也大,404 占比 6.8%,明显在扫一些被外链工具暴露过的旧参数 URL。它的行为更像传统搜索引擎的广度抓取,对站点结构干净程度的要求也高。

ClaudeBot 温和得多,请求数不高,路径集中在核心栏目页,404 很少。GPTBot 那一次请求很有意思:只抓了 robots.txt 就走了,之后两周再没出现。结合 OpenAI 官方文档的说法,GPTBot 的抓取有自己的调度节奏,低频不等于异常,但站点侧确实无法从日志里观察到它的索引意图。

为方便对照,把两类抓取目的的差异也整理成一张表:

对比项 训练数据采集型(GPTBot、ClaudeBot 等) 实时检索增强型(PerplexityBot 等)
抓取目的 收集语料用于模型训练,容忍延迟 为回答当前查询获取新鲜证据
抓取节奏 低频、周期性、全站广度 突发、按需、查询驱动
对时效的敏感度 低,旧内容也有训练价值 高,过期内容直接降低引用概率
复抓触发 调度器周期计划 用户查询命中且索引证据不足
站点侧可感知信号 日志里长期低频出现 突发流量加回答中带引用链接

从日志到结论:UA 反查,别被伪造 UA 骗了

统计到这一步还有一个隐患:UA 是客户端自己声明的,谁都能写 PerplexityBot。日志里就混着一个自称 AI 爬虫的可疑客户端,两周打了四千多次。要把它揪出来,得做正向 DNS 验证——官方爬虫的来源 IP 反向解析出来的域名,属于引擎自己的域名段,而且正向解析回去要能对上原 IP。验证代码只用标准库:

# 依赖:仅 Python 标准库(socket),3.8+ 可直接运行
# 场景:从日志里提出 AI 爬虫请求的来源 IP,逐个做正向 DNS 验证
import socket

# 各引擎官方公布的爬虫域名后缀,反解结果必须落在这些后缀里才算数
TRUST_SUFFIX = ("openai.com", "anthropic.com", "perplexity.ai")

def verify_bot_ip(ip: str) -> bool:
    # 第一步:把来源 IP 反向解析成主机名,失败即视为可疑
    try:
        host, _, _ = socket.gethostbyaddr(ip)
    except (socket.herror, socket.gaierror):
        return False
    # 第二步:把主机名正向解析回 IP,要求原 IP 在解析结果集合里
    resolved = {i[4][0] for i in socket.getaddrinfo(host, None)}
    # 第三步:域名后缀必须是官方网段,两个条件同时满足才通过
    return host.endswith(TRUST_SUFFIX) and ip in resolved

各引擎官方文档都写明了自己的验证方法(见文末参考),建议把这套验证固化成脚本,每次日志分析先跑一遍再进统计。我们靠它排掉了两个伪装 UA,其中一个反解出来是营销数据公司的域名。

踩坑复盘:四个真实踩过的坑

坑一:CDN 回源日志里丢 UA

这家企业官网前面挂了国内某 CDN。排查第一版结论明显不对——日志里 AI 爬虫请求数少得离谱。对了一个小时才发现,我们看的是 CDN 回源日志,部分静态资源请求在边缘节点就命中了缓存,回源日志里根本没有这些请求,自然也没有 UA。

结论:做 AI 爬虫分析必须看源站全量日志,或者从 CDN 控制台导出边缘日志;回源日志只能当参考,不能当证据。

这个问题在纯静态站上尤其隐蔽,静态资源占比高、回源率低,日志缺的正是大头。

坑二:UA 大小写混用

第一版 grep 用小写匹配,漏掉了一部分请求。抓回来的日志里,真实出现过的写法有 PerplexityBot/1.0,也有极个别全小写的 perplexitybot——后者后来验证是伪造。处理办法:识别环节统一用 grep -i 宽松匹配,验证环节再用上一节的 DNS 反查严格把关,两个环节分开,既不漏也不脏。

坑三:把营销扫描器当 AI 爬虫

日志里有个 UA 形如 Mozilla/5.0 (compatible; AIBotPro/2.0) 的客户端,名字带 AI,两周四千多次请求,一开始被算进了 AI 爬虫统计。反向 DNS 一跑,IP 归属是某个营销数据公司,跟任何 AI 引擎都对不上。类似的还有各种 SEO 工具箱爬虫:名字蹭 AI 关键词的,多半是扫描器,不是真在做 AI 检索的抓取。

结论:UA 声明可以随便写,IP 反向解析结果才相对可信。没有官方网段背书的 UA,一律先标记、不进统计。

坑四:robots.txt 放行 ≠ 会被引用

运维改 robots.txt 放行 GPTBot 和 PerplexityBot 之后,预期是「放行即引用」。两周过去,Perplexity 的抓取量上来了,回答里也开始引用;GPTBot 还是几乎不来。这里的认知偏差在于:robots.txt 只是准入门槛,不是抓取排程。放行之后来不来、多久来,由对方调度策略和站点内容的相关性、质量信号共同决定。

对实时检索型引擎还多一层:抓了页面也不代表会引用,抓取(fetch)和引用(cite)之间隔着质量评估。这一步发生在引擎侧,站点只能靠内容质量间接影响。这也是 GEO 实操里最容易想岔的一环——把抓取当成引用的前置条件即可,别当成承诺。

原理剖析:为什么不同 AI 引擎的抓取策略差这么多

底层原因在两类引擎对「抓取」的定义不同。

训练数据采集型的抓取服务于模型下一次训练。语料收集是批量、离线、低频的,一次全量抓取可能间隔数周甚至数月,调度器关心覆盖率而不是时效。这解释了 GPTBot 单次访问 robots.txt 后的长期沉默——它的抓取计划由 OpenAI 侧调度决定,跟单个站点的内容更新节奏关系不大。

实时检索增强(Retrieval-Augmented Generation, RAG)型的抓取服务于眼前这条正在拼装的回答。用户在 Perplexity 上问「附近哪家门店做 XX 服务」,引擎先查自有索引,证据不够新或不够准,才触发爬虫实时抓一批候选页。所以 PerplexityBot 的流量是脉冲式的:有用户问到相关话题才有流量,问的人越多抓得越勤。一个反直觉的推论是:对实时检索型引擎,长尾站点反而可能拿到更多按需抓取的机会,因为长尾查询在索引里缺新鲜证据,引擎更依赖即时抓取补位。

把实时检索型引擎从抓取到引用的完整链路画出来:

flowchart TD
    A[用户提出本地服务类问题] --> B[引擎判定需要新鲜网页证据]
    B --> C{自有索引是否有可用片段}
    C -- 有 --> F[片段进入回答并标注引用来源]
    C -- 无或已过期 --> D[调度爬虫实时抓取候选页]
    D --> E{页面可抓取且质量达标?}
    E -- 是 --> F
    E -- 否 --> G[换下一候选页 该页本轮失去曝光]
    F --> H[引用带来真实点击 反哺质量判断 影响复抓频率]

从这条链路能读出站点侧的三个杠杆:内容可抓取性决定页面能否进入候选池;内容质量与新鲜度决定能否在质量评估环节胜出;引用之后带来的真实点击反哺引擎对站点质量的判断,进而影响复抓频率。GEO 的全部技术动作,本质上都在撬这三个杠杆。

优化动作清单:日志结论怎么落地

基于两周观测,我们给这家企业列了一份按优先级排序的清单。三周后复查:PerplexityBot 的抓取深度从 6 级涨到 8 级,404 占比降到 0.9%,回答中的引用次数也有增长。清单如下:

内容可抓取性(优先级高)

  1. 核心服务页改为服务端渲染或静态化,确认浏览器禁用 JS 后正文仍完整可读;
  2. 详情页标题和首段写清「服务类目 + 服务城市 + 门店名」,给实时检索型引擎的片段抽取留干净的锚点;
  3. 修掉 6.8% 的 404 噪声:已下线页面配 301 跳转,参数 URL 在 robots.txt 里 disallow,别让抓取预算耗在死链上。

sitemap 与结构化信号

  1. sitemap.xml 拆成「服务」「门店」两份,内容更新后及时更新 lastmod;PerplexityBot 复抓延迟在 24 小时以内,说明它对 sitemap 变更是敏感的;
  2. 用 Schema.org 的 LocalBusiness 标注门店名、地址、营业时间,这一步不是给爬虫看的,是给引擎做实体对齐用的。

llms.txt 与 robots 策略

  1. 站点根目录加 llms.txt,把核心服务页、门店页链接和一句站点定位描述放进去,给愿意读它的引擎一个导览;
  2. robots.txt 对主流 AI 爬虫保持放行,Bytespider 是否放行按内容授权意愿自行决策——它抓取量最大、带宽占用最实在,值不值得放取决于你对训练数据授权的态度。

持续观测

  1. 把前面的统计命令写成每周跑一次的定时任务,请求数、404 占比、路径分布三项指标进内部看板,某 UA 突然归零这类异常当天就能发现。

误区澄清与收尾

排查收尾时,运营问得最多的那句是「怎么让 GPTBot 多来抓我们」。我的回答是:这个问题问错了对象。训练型爬虫来不来,站点侧可控的部分很少;真正可控、且被日志数据验证有效的,是把内容做实、把死链清掉、把结构化信号补齐,然后等实时检索型引擎在用户问到相关问题时选中你。AI 搜索引用与 SEO 收录是两套逻辑,前者吃内容质量与实体信息,后者吃链接与关键词布局,两套动作别混着考核。

趋势上判断,AI 爬虫的识别与验证会越来越重要:UA 可伪造,正向 DNS 验证目前是工程上可行的鉴别手段,各家引擎官方文档也都公布了验证方法,值得把流程固化下来。日志是站点侧少有的能直接看到「AI 是否在读取我」的窗口,把它变成例行监控,比每次出问题再排查省心得多。

如果你们站上也做过类似的 AI 爬虫日志分析,欢迎在评论区交流观测数据——不同行业、不同站型的抓取画像差异,本身就是很有信息量的东西。

参考与延伸

  • OpenAI 官方爬虫文档(GPTBot 等全部 UA 说明与 IP 验证方法):https://platform.openai.com/docs/bots
  • Anthropic 官方爬虫与日志治理选项说明(ClaudeBot 行为与控制):https://support.anthropic.com/en/articles/8894996-governance-and-logging-options-for-anthropic-crawlers-and-models
  • Perplexity 官方爬虫指南(PerplexityBot 抓取行为说明):https://docs.perplexity.ai/guides/bots
  • robots.txt 标准写法与历史(官方站点):https://www.robotstxt.org/robotstxt.html

AI 爬虫日志、GPTBot、PerplexityBot、UA 反查、robots.txt、GEO、AI优化AIO

🤖
本内容由 AI 辅助生成,经人工校对审核;部分素材、资料来源于公开网络,仅作个人观点分享与交流使用,无任何商业侵权意图。若内容、图片、文字涉及您的合法著作权、版权权益,请联系本人,核实后将第一时间删除、修改相关内容。