m. 子域的移动页 AI 搜索不认:响应式改造前后 AI 引用与抓取行为对照
上个月我们复盘一单零售电商的咨询时发现一个挺离谱的事:客户商城在 Perplexity 和 ChatGPT 里被引用的页面,全是三年前的老版本商品页——价格是旧的、活动是停了的,个别链接甚至指向已经下架的 SKU。问题落在了那个所有人都觉得「历史遗留、先不动」的 m. 子域上。整个排查加改造花了十一个工作日,这篇文章把过程和前后对照数据都摊开讲。
先交代背景。这家站点是典型的双端架构:www.example.com 跑桌面模板,m.example.com 跑独立移动模板,两端内容靠编辑在后台各发一份。移动端用了 Vary: User-Agent 的动态服务,同一个 URL 桌面 UA 和移动 UA 拿到的 HTML 不一样。而做生成式引擎优化(Generative Engine Optimization, GEO)的时候,第一个要确认的就是:AI 引擎的爬虫到底抓到了什么。
抓取日志摆出来,问题一眼就看见了
AI 引擎的爬虫 UA 基本是公开的:OpenAI 的 GPTBot、Apple 的 Applebot-Extended(AppleIntelligence 用来做训练和检索的那只)、PerplexityBot。我们拉了客户 nginx 十四天的访问日志,按 UA 过滤,再看每个 UA 实际请求的主机名。

结果是这样的:
| 爬虫 UA | 请求主机 | 占比 | 拿到的页面 |
|---|---|---|---|
| GPTBot | www.example.com | 92% | 桌面模板,内容与 m. 端不同步 |
| GPTBot | m.example.com | 8% | 移动页(桌面 UA 拿到精简版,部分资源 404) |
| Applebot-Extended | www.example.com | 97% | 桌面模板 |
| PerplexityBot | www.example.com | 100% | 桌面模板 |
说白了,AI 爬虫几乎全走 www。这本身正常——多数 AI 爬虫用类桌面 UA,配合 sitemap 和站内链接自然落到 www。真正的问题是:www 和 m. 的内容根本不是一回事。编辑双发,但 m. 端三个月前改版过一次,商品详情结构变了,部分老商品页在 m. 端已经停更,AI 引擎抓 www 拿到的还是旧版页面结构,引用的摘要自然也是旧的。
更坑的一点:m. 端给桌面 UA 返回的是「降级页面」——检测到非移动 UA 就吐一个精简 HTML,CSS 文件路径还是老版本的,全 404。就算 AI 爬虫偶然爬到 m. 端,拿到的也是半残页面。
用 curl 模拟一下就能复现。依赖与环境:任意 Linux/macOS 带 curl 7.68+,日志侧是 nginx 1.22。
# 依赖:curl 7.68+(任意 Linux/macOS 均可),用于桌面 UA 模拟
# 用桌面 UA 直接请求 m. 子域,模拟 GPTBot 的行为
curl -sI -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36" \
https://m.example.com/p/88231
# 返回头里这两行是关键,vary 头说明这里跑了动态服务
HTTP/2 200
vary: User-Agent
# 页面正文里引用的样式文件,路径指向老版本目录:
# /static/v2/css/detail.min.css —— 这个版本目录在 m. 端早已下线,直接 404
同一批日志里我们还对比了 Googlebot,它走 www、抓桌面版、由 Google 自己做移动适配判断,所以传统搜索这块没出问题。这也解释了为什么客户 SEO 团队一直没察觉——传统搜索引擎容错好,AI 引擎容错差。
AI 引擎处理双端内容的机制:一条时间线看懂
把整个抓取-引用链路画成时序图,团队里其他同事一看就明白了,比嘴讲省事。
sequenceDiagram
participant AI as AI 引擎爬虫(桌面 UA)
participant W as www.example.com
participant M as m.example.com
AI->>W: 抓取商品页(桌面 UA)
W-->>AI: 返回旧版桌面 HTML
Note over AI: 抽取正文入库,作为引用语料
AI->>M: 偶尔抓 m. 端(概率低)
M-->>AI: 桌面 UA 命中动态服务,返回精简降级页
Note over AI: 资源 404,抽取失败或拿到残缺内容
AI->>AI: 语料库中 m. 端内容停留在改版前
Note over AI: 用户提问时引用旧价格、旧活动
问题不止一处,我们内部列了三条:
- www 与 m. 内容双发,编辑漏发、结构不同步,AI 语料自然陈旧;
- m. 端对桌面 UA 的动态服务返回降级页,AI 爬虫抓到的基本是废页;
- 两端没有 canonical 互指,
<link rel="alternate" media="...">只写在 www 端,m. 端连回指都没有。
先诊断清楚,再动手
动手前我们做了一次系统性的对比验证,主要三个动作。第一,桌面 UA 和移动 UA 各抓一遍同一批 200 个商品页,diff 内容相似度。第二,从日志里按周统计 GPTBot / Applebot-Extended 对两个主机的抓取量和返回码分布。第三,拿 ChatGPT、Perplexity、豆包各问 20 个商品相关的问题,记录引用来源和摘要新鲜度,作为改造前的基线。
诊断结论汇总:
| 检查项 | www 端 | m. 端 |
|---|---|---|
| 内容新鲜度 | 旧版模板,3 个月未更新结构 | 部分页面停更,2 个类目整组缺失 |
| 桌面 UA 响应 | 正常 200 | 200 但资源大面积 404 |
| canonical 指向 | 指向自身 | 无 canonical |
| alternate 标注 | 有 rel=alternate media | 无回指 |
| AI 引用摘要新鲜度 | 基线:约三成引用停留在旧价 | 几乎不被引用 |
这里的关键判断:与其修补双端同步机制,不如直接收敛到单端。 双端动态服务这套东西是 2015 年前后的主流方案,放在今天的响应式改造里属于白费劲——AI 爬虫不会像 Googlebot 那样贴心地模拟移动环境,桌面 UA 拿到什么就是什么。
改造方案三步走,画个流程图:
flowchart TD
A[现状:www 与 m. 双端双发] --> B{第一步:内容合并}
B --> C[m. 端独有内容合入 www 响应式模板]
B --> D[比对新旧页面 URL 映射表]
C --> E{第二步:301 收敛}
D --> E
E --> F[m.example.com 全站 301 到 www 对应页]
E --> G[保留 m. 端 30 天过渡期日志监控]
F --> H{第三步:标签清理}
G --> H
H --> I[删除 rel=alternate media 标注]
H --> J[www 端 canonical 统一指向自身]
I --> K[提交新 sitemap,观察 AI 抓取行为变化]
J --> K
响应式改造 + 301 收敛的具体做法
内容合并阶段最花时间的是 URL 映射表。m. 端有 1.7 万个商品页,其中 800 多个在 www 端没有一一对应(早年做移动专享活动留下的页面),这些要么合入 www 的新页面,要么明确废弃。我们用 Python 写了个比对脚本,依赖:Python 3.11、requests 2.31;环境:Ubuntu 22.04。
# 依赖:Python 3.11、requests 2.31;环境:Ubuntu 22.04
import requests
import csv
from concurrent.futures import ThreadPoolExecutor
# 读入 m 端 URL 清单,逐条用桌面 UA 请求 www 端对应页
def check_pair(m_url, www_url):
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
try:
r = requests.get(www_url, headers=headers, timeout=10)
# 状态码非 200 就记入待人工处理清单
if r.status_code != 200:
return (m_url, www_url, r.status_code, "需映射或废弃")
# 再检查 www 端页面是否包含核心内容块
if "product-detail" not in r.text:
return (m_url, www_url, r.status_code, "模板缺内容块")
return (m_url, www_url, r.status_code, "OK")
except requests.RequestException as e:
# 网络异常单独归类,避免和内容缺失混淆
return (m_url, www_url, -1, f"异常:{type(e).__name__}")
# 主流程:两列 CSV 读入,线程池并发校验映射完整性
with open("url_map.csv") as f:
pairs = [(row["m"], row["www"]) for row in csv.DictReader(f)]
with ThreadPoolExecutor(max_workers=16) as pool:
results = list(pool.map(lambda p: check_pair(*p), pairs))
# 结果落盘,交给编辑确认 800 多个无对应页面
with open("map_check_result.csv", "w", newline="") as f:
csv.writer(f).writerows(results)
301 收敛的 nginx 配置很简单,但有个细节值得记:m. 端的老路径和 www 端不完全一致(比如 /p/88231 vs /product/88231),要用映射表做 rewrite 而不能整域 301 到首页。
# 依赖:nginx 1.22,映射表 map 文件由 Python 脚本每日生成
# m. 子域 server 块:全站 301 收敛到 www
# 用 map 指令做路径级重写,避免整域跳首页丢链接信号
map $uri $www_target {
default /;
# 映射表覆盖 m 端老路径到 www 新路径
include /etc/nginx/conf.d/m_to_www.map;
}
server {
listen 443 ssl;
server_name m.example.com;
# 有映射的路径按表跳转,没有的回首页而不是 404
location / {
return 301 https://www.example.com$www_target;
}
# 健康检查路径保留 200,方便监控确认子域还活着
# 这条必须放在 location / 之前生效范围内,精确匹配优先级最高
location = /healthz {
return 200 "ok";
}
}
标签清理这块,改完之后 www 端页面 head 里删掉了原来那行 <link rel="alternate" media="only screen and (max-width: 640px)" href="https://m.example.com/...">,m. 端全站 301 之后也就不存在回指问题了。canonical 保持每页指向自身。这套做法和 Google 对响应式设计的官方建议一致,也符合 schema.org 对页面结构化标注的一般要求。
改造前后:AI 引用与抓取行为对照
改造完成后我们继续观察了四周,抓取日志和引用测试都重跑了一遍。前后对照数据如下(均为我们站点的实测口径,不代表普遍水平):
| 指标 | 改造前 | 改造后第四周 |
|---|---|---|
| GPTBot 抓取 m. 端占比 | 8% | 0%(全站 301,爬虫跟随跳转落 www) |
| GPTBot 抓取 www 返回 200 比例 | 87% | 99.6% |
| Applebot-Extended 周均抓取页面数 | 约 2,400 | 约 5,900 |
| ChatGPT 引用摘要价格新鲜度 | 约三成停在旧价 | 四周内未再出现旧价引用 |
| Perplexity 引用来源落在 www | 100% | 100%(且摘要含新活动信息) |
| m. 端遗留 404 告警 | 每周 30+ 条 | 归零 |
几个值得说的观察。GPTBot 对 301 的跟随非常干脆,m. 端停服后一周内抓取就完全转移到 www 了。Applebot-Extended 抓取量涨了一倍多,我们猜是因为 m. 端大量重复/降级页面之前稀释了抓取预算,收敛后有效页面密度上去了——这个归因没有官方依据,只是日志侧的推断。Perplexity 的引用摘要里开始出现改版后的新版商品描述,说明它的语料在跟着新版页面刷新。
给还没动手的团队三条可执行建议:
- 先查日志再谈方案,AI 爬虫的 UA 和主机分布摆在那里,猜是猜不出来的;
- 双端双发的站点优先考虑收敛到响应式单端,动态服务加
Vary: User-Agent这套老方案对 AI 抓取极不友好; - 301 必须带映射表,整域跳首页等于把积累的链接信号全扔了。
收尾
做 GEO 这段时间最大的感受是:AI 引擎比传统搜索引擎「认死理」,它不太帮你做移动适配的兜底,你给它什么它就引用什么。历史遗留的 m. 子域在传统 SEO 时代还能靠 alternate 标注混过去,到了 AI 搜索时代就是明晃晃的内容黑洞——你在上面发的每一篇内容,AI 引擎要么抓不到,要么抓到的是半残页。趋势上看,独立移动站会越来越少,响应式单端加上干净的结构化标注会成为默认架构。
坑我们已经踩完了,你在 m. 子域或者动态服务上踩过什么别的坑,评论区聊聊。
参考与延伸
- schema.org 官方站点:https://schema.org
- Google 搜索中心关于响应式设计(移动站点设计)的文档:https://developers.google.com/search/docs/crawling-indexing/mobile/mobile-sites
- MDN 关于 Vary 响应头的说明:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Vary
- Google 搜索中心关于重定向与 Google 搜索的文档:https://developers.google.com/search/docs/crawling-indexing/301-redirects
关键词:GEO、AI搜索、响应式设计、301重定向、canonical标签、移动子域、电商站AI推荐