m. 子域的移动页 AI 搜索不认:响应式改造前后 AI 引用与抓取行为对照
适用读者:负责零售电商站点架构和 SEO/GEO 的技术人员;还在用独立 m. 子域做移动站的团队;正在排查自家内容在 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/2200vary: User-Agent# 页面正文里引用的样式文件,路径指向老版本目录:# /static/v2/css/detail.min.css —— 这个版本目录在 m. 端早已下线,直接 404同一批日志里我们还对比了 Googlebot,它走 www、抓桌面版、由 Google 自己做移动适配判断,所以传统搜索这块没出问题。这也解释了为什么客户 SEO 团队一直没察觉——传统搜索引擎容错好,AI 引擎容错差。
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 拿到什么就是什么。
改造方案三步走,画个流程图:
响应式改造 + 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.04importrequestsimportcsvfromconcurrent.futuresimportThreadPoolExecutor# 读入 m 端 URL 清单,逐条用桌面 UA 请求 www 端对应页defcheck_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 就记入待人工处理清单ifr.status_code!=200:return(m_url,www_url,r.status_code,"需映射或废弃")# 再检查 www 端页面是否包含核心内容块if"product-detail"notinr.text:return(m_url,www_url,r.status_code,"模板缺内容块")return(m_url,www_url,r.status_code,"OK")exceptrequests.RequestExceptionase:# 网络异常单独归类,避免和内容缺失混淆return(m_url,www_url,-1,f"异常:{type(e).__name__}")# 主流程:两列 CSV 读入,线程池并发校验映射完整性withopen("url_map.csv")asf:pairs=[(row["m"],row["www"])forrowincsv.DictReader(f)]withThreadPoolExecutor(max_workers=16)aspool:results=list(pool.map(lambdap:check_pair(*p),pairs))# 结果落盘,交给编辑确认 800 多个无对应页面withopen("map_check_result.csv","w",newline="")asf:csv.writer(f).writerows(results)301 收敛的 nginx 配置很简单,但有个细节值得记:m. 端的老路径和 www 端不完全一致(比如/p/88231vs/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推荐
ozilla.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推荐