m. 子域的移动页 AI 搜索不认:响应式改造前后 AI 引用与抓取行为对照

2026-10-01 01:16:26 1 次浏览
GEO响应式设计301重定向canonical标签移动端适配爬虫日志分析

上个月我们复盘一单零售电商的咨询时发现一个挺离谱的事:客户商城在 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推荐

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