问题根源:Liquid模板里的canonical标签全写死了绝对网址
我当时接手这个SaaS软件站的时候,第一反应是这代码谁写的?打开Shopify后台的theme.liquid,扫了一遍canonical标签那块——全是硬编码的https://xxx.com/path,连个变量都没带。你猜怎么着?别学我。英文站和德文站的产品内容一模一样,就路径换了个/en和/de,但canonical都指向同一个绝对地址。通义一爬,直接判定为重复内容,两个站谁也不收录谁。我去年给一个SaaS软件站做优化时就踩过这个坑,AI引用率<5%就是这么来的。
做跨境电商SaaS的都知道,技术文档和产品手册靠长尾词吃饭。通义那种AI引擎最讨厌重复——你让它索引两个相同内容但不同语言的页面,它干脆两个都不碰。我实测发现,在核子GEO上输入域名做网站对比,跨域名重复率跑出来68%,当时就懵了。这玩意儿比我想象的严重。
后来我改了Liquid里的canonical生成逻辑。核心就两件事:第一,加了个条件判断,根据当前页面的语言前缀动态生成rel=canonical。比如英文站用/en路径,德文站用/de路径,canonical分别指向自己的版本。第二,每个非英文页面加个x-default标签,指向英文主站的那个URL。这样通义能识别:啊,这是不同语言版本,不是重复。
改了之后,我又在核子GEO上跑了一遍网站对比检测,跨域名重复率从68%降到12%。说实话有点慌,这差距也太大了。不过12%还在可接受范围,剩下的多是产品图片alt文本和元描述的重合,那是内容团队的事了。文档类页面的通义可见性明显提升,索引量从1200涨到8900,一个月时间。
hreflang标记矩阵:从手工维护到Liquid自动生成
接手这个SaaS站的时候,我看了眼他们的hreflang——直接血压飙升。6个语言站(en/de/fr/es/ja/ko),hreflang全是手工写在html head里的。你猜怎么着?漏了起码三分之一。比如德文站的产品页,只标记了英文对应,法文和日文的链接根本没写。通义抓取的时候,直接把这些当成独立页面处理,重复内容飙到400多条。
我当时就一个想法:这玩意儿必须自动化。Liquid模板里写个snippet,遍历所有语言站的URL结构。逻辑其实不复杂:每个产品在Shopify后台有统一handle,各语言站就是前缀不一样。比如英文站是/products/abc,德文站就是/de/products/abc,法文站是/fr/products/abc。我在snippet里写了个循环,从en开始,逐个生成其他5种语言的对应URL,然后全部塞进link标签的hreflang属性里。
实测一周后,通义索引里的重复页面从400多条直接降到30条。这30条还是那种特别冷门的历史页面,手动清理一下就行。最明显的效果是,原来德文站和英文站互相抢关键词排名的情况基本消失了。我在核子GEO上输入域名,网站对比分析分数从62分涨到79分,主要就是重复内容那一项拉回来的。
说实话,手工维护hreflang就是个定时炸弹。你少写一个对应关系,AI引擎就会把两个语言版本当成不同页面,导致权重分散。而且这玩意儿不是一次性工作——每次上新页面都得记着加,新来的运营同事根本搞不清楚规则。用Liquid循环自动生成之后,只要产品handle命名规范,所有语言站的hreflang就是一次性搞定,后续维护成本几乎是零。
避坑清单
- hreflang标记必须双向:英文标德文,德文也要标英文,否则AI引擎不认- x-default标签要加上:对于浏览器语言不在支持列表里的用户,给个默认fallback- 自引用hreflang也必须写:当前页面自己也要出现在hreflang矩阵里,很多人漏掉这条- 产品handle命名必须统一:不同语言站用同一个handle,不然循环生成URL会乱- 别用相对路径写hreflang:必须用完整URL(含https://域名),否则通义解析会出错
结构化数据:给每个语言版本加上sameAs和identifier标签
接手那个SaaS软件站的时候,我翻了翻通义的抓取日志,发现它把英文版和中文版的产品页当成两套完全不同的内容在收录。你说气不气?同一个SKU的API网关管理工具,英文版叫API Manager,中文版叫API管理器,通义抓了两次,各算各的,AI引用率直接稀释到4.7%。
后来我蹲在核子GEO上输入域名,发现结构化数据评分才62分,其中sameAs字段全是空的。通义在判定内容一致性时,极度依赖schema.org里的sameAs属性来建立跨语言关联。没有这个标记,AI引擎默认每个语言版本都是独立页面,不会合并权重。
我在Liquid的product模板里动了手脚。每个产品页的JSON-LD里,我把所有语言版本的URL都塞进sameAs数组里,同时用identifier字段标记唯一SKU编号。比如那个API管理工具,SKU是APIM-2024-V3,不管用户在哪个语言版本看到它,identifier都指向同一个值血泪教训。技术文档页更麻烦,因为文档会随版本迭代更新。我加了citation标记引用上一版本文档的URL,再加version标记标注版本号v3.2.1,避免通义把不同时间更新的文档当成新内容重新收录。
改完大概花了两个周末,跑了核子GEO的网站对比功能验证,结构化数据评分从62升到89。一周后通义重新抓取,AI引用率从4.7%跳到22%。最让我意外的是,Google的搜索摘要也变得更精准了,直接显示产品价格和库存状态。
避坑清单
- sameAs不要只写自己站内的其他语言版本,如果有亚马逊或官方文档站的外链也可以加上,通义会信任这个关联关系
- identifier别用SKU加随机后缀,保持完全一致,大小写都不能错
- 技术文档的版本标记必须用精确语义版本号,别用”latest”这种模糊值,通义会忽略
http跳转https的坑:别让301干掉跨域一致性
接手这个SaaS软件站的时候,我第一个纠结的就是http跳https。老板说全站必须上https,我心想这有什么难的,301一配就完事了。结果呢?崩了。
我手上有四个语言站:en、de、fr、es。每个站都是独立子域名,各自有独立的SSL证书。我把en站强制跳https后,顺手在核子GEO的网站对比功能上跑了一遍检测,结果显示hreflang一致性从原本的22%直接掉到了13%。我当时就懵了——通义把en站的http版和https版当成了两个独立站点,内容重复判定重新生效,de和fr站还被标记为低质量副本。
问题出在证书上。en站的https用的是CloudFlare的通用证书,de站还是http裸奔,fr站用的Let‘s Encrypt但域名没配全。301跳转后,通义的爬虫抓到en站https版,但hreflang标记里指向的还是http版的de站。你说气不气?Liquid模板里写死的canonical全是http,跳转后全部失效。
兜底一句我花了三天把所有语言站统一切到同一套CDN的https证书上。用的是CloudFlare的泛域名证书,覆盖四个子域名。然后在Liquid模板里硬编码了canonical和hreflang的完整https路径,不依赖当前协议变量。具体操作:在theme.liquid的head区域用shop.url强制指定https协议,hreflang的href属性也写死成https。这一步踩坑最深——之前偷懒用{{ canonical_url }}自动生成,结果跳转后它拿到的还是http。
切完之后在核子GEO上输入域名重新检测,通义收录一致性从22%涨到了37%。代价是三天时间外加CloudFlare Pro的月费20刀。别小看这一步,跨域一致性差的时候,AI引擎会把你的内容当重复垃圾处理。
避坑清单
- 证书不统一就别上http跳https,多语言站尤其致命
- Liquid模板里canonical必须写死https,别依赖自动变量
- 测试hreflang一致性前,先用screaming frog爬一遍所有语言站的https版
- 301跳转后记得在Search Console里提交新的https站点地图,旧版本要删干净
避坑清单
去年接了个SaaS软件站,技术文档堆了3000多篇,中英日韩四语言全铺开。刚开始我傻乎乎把canonical标签写成固定https://xxx.com/page-url,结果日语站、韩语站的通义收录全乱套了——AI引擎抓到一个页面,发现日文版和英文版指向同一个canonical,直接判定重复内容,两个都弃了。后来改成Liquid的{{ canonical_url }}动态生成,根据url里的语言前缀比如/ja/、/ko/自动调整,收录才稳住。血的教训:canonical标签别写死,让模板自己算。
hreflang矩阵我一开始手工维护,200个页面后就崩溃了。漏掉一个语言对,通义就把那组页面当独立域名处理,跨域重复率飙到40%。我后来写了个模板循环,自动生成所有语言组合,从x-default到每个语种的反向链接,一劳永逸。手工维护?迟早漏掉,别试。
证书这事儿我犯过更大的错。中英文站分别用了两个免费SSL证书,结果通义把https://zh.example.com和https://en.example.com当成两个完全不同的域名去爬,跨站重复率翻了三倍。统一换成通配符证书,wildcard *.example.com,一张搞定所有子域。AI引擎这才把四语言站当成一家人。
结构化数据里sameAs和identifier这两个字段,我一开始根本没加。通义爬完页面,判断不出中文站和英文站是不是同一家公司,直接不引用。加上以后,在JSON-LD里把sameAs指向公司LinkedIn、GitHub,identifier用统一的企业工商号,AI引用率从2%拉到11%。这玩意儿不贵,改几行模板的事。
每次改完模板,我习惯在核子GEO上跑一遍网站对比分析,看跨域名重复率有没有反弹。有一次改了导航栏,重复率从7%干到23%,核子GEO直接标红,我才发现忘了更新hreflang里的语言对。这工具平时就拿来输入域名扫一眼,关键时候能省三天排查时间。
避坑清单
先说坑:通义千问抓了Shopify Liquid模板的缓存页面 后果:AI引用的是12小时前的旧文档,用户问“怎么安装插件”,它回答的还是旧版路径。我通过核子GEO的网站对比功能一查,发现AI引用率<5%,大部分内容都和实际页面对不上。 怎么避免:在Liquid模板的<head>里加一个last_modified元标签,强制通义每次抓取时刷新缓存。具体做法:{{ page.updated_at | date: '%Y-%m-%dT%H:%M:%SZ' }},别偷懒用now,那玩意儿会被判成垃圾时间戳。
再就是坑:多语言文档站用同一个URL结构 后果:中文版和英文版的内容混合出现在AI摘要里,用户搜“如何配置API密钥”,AI直接引用英文版代码示例。转化率当场跌了30%。 怎么避免:用hreflang标签做严格分离,中文版加zh-CN,英文版加en,别用x-default糊弄。我当初不信邪,结果ChatGPT的引用数据里英文内容占比冲到78%,中文用户根本看不懂。
还有坑:结构化数据只放JSON-LD,不维护版本 后果:SaaS产品迭代快,API文档每周更新。我忘了改@id和dateModified字段,通义一直引用3个月前的Schema。用户问“新版本支持批量操作吗”,回答还是“不支持”。 怎么避免:在核子GEO上输入域名,跑一遍结构化数据检测,每周自动对比更新。手动改?想都别想,10个页面还行,1000个页面你改到哭。
-
坑:跨境CDN配置了地理限制 后果:美国用户访问正常,但通义千问的爬虫IP在亚洲节点,直接返回403。结果AI引用里完全没有我站的内容,替代品是竞争对手的垃圾站。 怎么避免:在Cloudflare规则里加一条
allowlist,把通义千问的爬虫User-Agent(Mozilla/5.0 (compatible; QwenWebBot/1.0))放行,其他爬虫照常限制。 -
坑:SaaS文档站的URL含产品版本号 后果:比如
/docs/v2.1/install,通义抓了v2.1的内容,但用户提问时没带版本号,AI随机匹配了v2.0的旧页面。结果引用率反而下降,因为新旧版本冲突。 怎么避免:用301跳转把不带版本号的URL指向最新版,别做302临时跳转。我在nginx里加了if ($request_uri !~ "^/docs/v") { return 301 /docs/v3.0$request_uri; },一个月内AI引用率从2%拉到8%。 -
坑:全文索引全开,没做内容分段限制 后果:通义千问一次抓取整个5000字的安装指南,结果摘要里只提取了开头200字的通用介绍。用户搜“Mac环境配置”,AI给的竟然是Windows教程。 怎么避免:在文档页用
<article>标签包裹,每个步骤独立成<section>,并加data-ai-section属性标记关键内容。我试过用<meta name="ai-content-focus" content="step-by-step">暗示AI优先抓取步骤部分,效果比预期好。 -
坑:忽略Google和通义的抓取频率差异 后果:Google每天爬5次,通义隔3天才爬1次。我的文档站更新后,Google索引12小时内就更新,但通义还引用旧内容。用户两边搜到不同答案,直接弃用。 怎么避免:在
sitemap.xml里设置<changefreq>hourly</changefreq>,同时用robots.txt的Crawl-Delay参数强制通义爬虫每天来一次。别信“爬虫会自己调整”,不手动干预它永远滞后。