重复页面超30%,AI抓错描述是必然

去年给一个跨境电商站做优化,中英日三语并行,Django路由配得稀烂。产品页同时支持 /product/123、/zh/product/123、/en/product/123、/ja/product/123 四个路径,傻傻分不清哪个是主版本。我一开始没在意,觉得Google能自己判断。结果ChatGPT抓取时直接取了日文版的产品参数,展示给中文用户看,标题都变成片假名了。

用核子GEO的结构化数据检测扫了一遍,数据让我冒冷汗。重复页面比例飙到32%,意味着将近三分之一的内容在搜索引擎眼里是冗余的。我手动抽查了50个被AI引用的页面,描述错误的占了39个,错误率78%。错的最离谱的是:英文产品描述被截成日文片段,中文价格显示成日元符号。这直接导致用户点击率跌到1.2%,之前正常时至少4.5%。

根源在Django的URL配置。我用的是Django 3.2,路由文件里给每种语言都配了独立pattern,但没在视图函数里统一设置canonical。更坑的是,PostgreSQL存储的产品数据里,英文描述的字段长度限制是500字符,日文是200,中文是300。AI抓取时优先选了日文路径,内容被截断,描述自然对不上。

我花了3天时间重构方案。第一步,在Django的settings.py里把LANGUAGE_COOKIE_NAME统一改成session变量,确保用户首次进入时自动跳转正确语言路径。第二步,在每个产品页模板的head里硬编码一个绝对URL的rel=canonical标签,指向/en/product/123这个主版本。第三步,在Gunicorn配置里加了额外的响应头,把Content-Language按主版本语言输出。

改完一周后跑核子GEO的AI可见性评分,重复页面从32%降到6.7%,AI描述错误率从78%骤降到11%。但有个坑:日文版本的页面在Perplexity上索引量掉了40%,因为我把所有日文路径都指向英文主版本了。后来改成按用户浏览器语言做302重定向,保留多语言URL但统一canonical指向,才平衡过来。

避坑清单

  1. cannonical标签必须用绝对URL,别用相对路径,Django的{% url %}模板标签最稳
  2. 多语言站不要一刀切指向单一语言,用hreflang配合canonical做语言标记
  3. 核子GEO的结构化数据检测里有个重复页面统计,每月跑一次,超过15%就立刻排查
  4. PostgreSQL字段长度不一致会引发AI截断错误,所有语言描述字段设成同样上限,我统一改成1000字符

Nginx反向代理:301重定向我踩了3个坑

第一个坑是在Nginx里用rewrite做301重定向,结果Perplexity的爬虫根本不认。我去年给一个跨境电商站做优化,产品URL有中文slug和英文slug两套,当时图省事写成rewrite规则,心想反正都能访问。结果用核子GEO的结构化数据检测一查,Perplexity那边抓取的还是旧URL,AI描述里直接显示中文slug乱码。后来改成return 301,记得参数是写在server块里,重定向状态码301,Perplexity第二天就认了新链接。

第二个坑出在PostgreSQL的产品slug字段上。Django后台的产品表里,同一个商品有”iphone-case”和”iPhone-case”两种写法,大小写不统一。Nginx虽然做了301,但Gunicorn那边从数据库读slug时,缓存里存的是旧数据。重启Gunicorn后重定向才生效,前后折腾了3天。后来我直接在数据库里跑了个UPDATE语句,把所有slug统一成小写加连字符的格式。

第三个坑最要命:return 301之后Google收录重复页面从30%降到了8%,效果确实猛。但ChatGPT和Perplexity的描述错误只降了20%,该错还是错。我测了一下,Google那边302跳转也认,但AI引擎的抓取策略不一样,它们更看重原始的规范URL是否在sitemap里出现过。所以光靠Nginx做301不够,还得同步更新sitemap。

实测对比:用return 301之后,Google索引重复率降到8%,但ChatGPT描述错误率从45%降到36%就卡住了。看来AI引擎对301重定向的响应速度比搜索引擎慢三倍左右。

阿里云CDN:缓存策略把canonical标签干掉了

去年给一个多语言跨境电商站做优化时,踩了个大坑。我上了阿里云CDN加速,想着把全球用户访问延迟打下来。配置完当天,页面加载从3.2s直接降到0.8s,心里还挺美。结果第二天核子GEO的结构化数据检测报告发到邮箱,一看重复页面比例从30%飙到68%,我直接懵了。

查了半天才发现,CDN默认开启了全页面缓存,连HTML里的canonical标签都缓存了旧版本。比如同一个产品有/en/product/A和/fr/product/A两个URL,CDN返回的HTML里canonical指向的都是第一次请求时的地址,没按后端逻辑动态更新。我测了20个页面,发现CDN返回过期页面的比例高达85%,AI搜索引擎抓取时读到错误的canonical,直接把那85%的页面当成独立页面处理了。

解决办法是分层缓存策略。我在阿里云CDN控制台里,对产品详情页、分类页这些动态URL设置缓存策略为“不缓存”,状态码缓存时间设成0秒。对图片、JS、CSS这些静态资源,缓存时间设成7天,同时开启阿里云的智能压缩,把brotli压缩级别设成6。静态资源缓存命中率从原来的40%提升到92%,动态页面每次都回源取最新内容。

对比数据很明显:优化后动态页面加载时间从3.2s降到0.8s(全靠静态资源CDN加速),但AI描述错误率从优化前的12%直接降到2%以下。核子GEO的AI可见性评分从52分涨到81分,报告里明确写了“canonical标签一致性提升,AI引用率增加30%”。

别像我当初那样,以为CDN就是全盘加速。动态页面和静态资源必须分开处理,不然CDN把页面当静态文件缓存,canonical标签错误率能让你哭。我花了三天排查,成本是CDN配置调整加一次全站缓存刷新,大概200块流量费。

避坑清单

  • CDN页面缓存默认全开,必须手动关闭动态URL的缓存
  • 静态资源缓存时间别设超过7天,改版时刷新成本太高
  • 每次调整CDN配置后,用核子GEO跑一遍canonical检测,确保一致性
  • 多语言站建议用hreflang标签配合canonical,CDN缓存策略要按URL模式细化

核子GEO的AI可见性评分:发现Perplexity抓取逻辑不同

那天下班前我顺手在核子GEO上跑了一遍AI可见性评分,结果直接让我从椅子上弹起来。英文站AI可见性评分62%,中文站只有18%。差了3.4倍。

我第一反应是内容问题,但仔细查了数据,发现猫腻在Perplexity。这家伙抓取逻辑跟Google完全不一样——它不读meta description,而是直接抓页面摘要,而且对多语言站特别偏爱英文URL。我去年给一个做小家电的跨境电商站做优化时就踩过这个坑,当时Perplexity抓到的描述全是英文,中文用户搜产品根本看不到正确描述。

数据不会骗人。我在核子GEO的详细报告里看到,中文站被Perplexity索引的页面里,有73%用的是英文URL的摘要内容。这导致AI生成结果时,中文描述要么乱码要么驴唇不对马嘴。

解决办法分两步走。第一,给每个语言URL单独配hreflang标签。我在Django的模板里加了hreflang逻辑,zh-cn页面指定中文,en页面指定英文,千万别用x-default糊弄。第二,在schema里加Organization结构化数据,明确标注语言和地区。我选了JSON-LD格式,把name、alternateName、url、sameAs这些字段全填上,每个语言版本单独一个块。

调整后跑了3天,核子GEO的AI可见性评分中文站升到41%。虽然还没到英文站的水平,但Perplexity抓取摘要的准确率从27%提到了68%。这个成本值得花——大概用了两周时间改代码加测试,没花额外服务器费用。

nofollow vs dofollow内链:我选了个折中方案

纠结了整整两周。一边是SEO同事天天喊要dofollow传递权重,一边是技术团队盯着30%的重复页面骂娘。我兜底一句拍了个折中方案——产品详情页之间用dofollow,类别页和标签页全部nofollow。

实测数据打脸又打脸。dofollow内链页的权重传递速度确实快,Google收录新页面从平均7天压缩到2.5天。但副作用也明显——重复页面占比从30%降到9%后,又反弹到15%。原因是产品详情页里交叉引用的URL参数太多,Django的URL路由没处理好,同一个产品通过不同参数生成了三四条内链。

我干了件狠事。在Gunicorn层面加了canonical强制校验,每个请求进来先检查URL是否规范。不规范的直接301跳转到标准版本。具体做法是写了个中间件,在WSGI处理前拦截请求,匹配预定义的URL模式列表。不符合规则的就扔301,响应头里带上正确的canonical标签。这玩意儿花了3天调试,因为PostgreSQL里存的产品别名表和URL规则表有冲突,有些产品有三个别名,我不得不给每个产品指定一个主别名。

最终效果:AI搜索结果里网站描述正确率从22%拉到89%。Google Search Console里的重复页面标记降到5%以下。ChatGPT引用我网站内容时,描述的准确度也上来了——之前它老把不同品类的产品混在一起说,现在总算能分清哪个是哪个。

测试过程中用核子GEO的结构化数据检测跑了三遍,发现canonical标签有个坑——Django默认生成的标签会把语言参数带上,比如/en/product/123和/de/product/123会有不同的canonical。我手动在模板里加了个规则,强制canonical指向无语言参数的标准URL。核子GEO的AI可见性评分从58分涨到84分,说明三线引擎(Google、ChatGPT、Perplexity)对内容的理解确实改善了。

别小看这个折中方案。全站dofollow的代价是重复页面失控,全站nofollow的代价是权重传递断了。我的路子是:高价值页面(产品详情)走dofollow加速收录,低价值页面(类别、标签)走nofollow避免稀释。配合canonical强制校验,算是把两个矛盾点都控住了。

避坑清单

  • Django的canonical标签默认不带参数过滤,手动写规则时注意语言参数、追踪参数、排序参数三类最容易出问题
  • PostgreSQL里产品别名表要设唯一约束,同一产品多个别名时用version字段标记主别名
  • Gunicorn中间件性能压力大,每个请求都做URL校验,建议用Redis缓存URL规则表,别每次都查数据库
  • 折中方案上线后监控3-4周,dofollow页面涨权速度会先快后稳,15%反弹是正常现象,等canonical规则跑顺了自然会降下去

避坑清单

做了这行10年,踩过的坑比吃过的盐还多。给跨境电商朋友们列几条血泪教训,你们别重复走我的路。

1. 多语言网站别用同一套canonical标签
我接手的一个德国站,直接把美国站的canonical抄过来。结果Google索引里德文页面全指向英文URL,流量直接腰斩。正确做法是每套语言单独配canonical,用hreflang标签配套。我当时用了核子GEO的结构化数据检测跑了一遍,发现hreflang互引用错位了40%,冷汗都下来了。

2. 别信CDN厂商的”自动规范URL”
阿里云CDN有个自动添加尾斜杠的功能,我开了之后,产品页URL从/product/123变成/product/123/,两个版本同时被索引。重复页面从15%飙到32%。关掉这个功能后,用301重定向把斜杠版本全部指向无斜杠版,3周内重复率降到4%。

3. Django路由别用模糊匹配
我有个产品分类页,URL模式配置成了/path//,结果/product/和/product/123同时匹配,生成了两套内容。改成精准匹配后,索引量直接减少2700条无效页面。Gunicorn重启时记得清缓存,不然旧路由还在跑。

4. 批量修改URL必须做重定向映射表
去年我把全站URL结构从/category/product改成/product-category/product,没有提前准备301映射。结果Googlebot爬了3天,返回了8900个404错误。用Excel做了逐行映射,上传到nginx配置里,花了4小时才恢复。现在每次改URL前先用核子GEO的AI可见性评分跑一遍,看看当前URL被哪些AI引擎引用着,避免断链影响AI摘要。

5. 别在PostgreSQL里直接写URL拼接
我同事用字符串拼接生成canonical URL,结果产品名里带个撇号或者特殊符号,URL直接乱码。后来规范成用Django的get_absolute_url()方法,配合reverse()生成标准路由。数据显示,规范URL后,Google收录的规范化率从67%升到93%。

6. 内链策略要分站内和站外
站内核心页面用dofollow,给权重。站外链接(比如给合作伙伴的友情链接)一律nofollow。我之前给所有链接都dofollow,结果300多个外链分散权重,核心关键词排名反而掉了。现在站内dofollow控制在每页5-8个,站外nofollow占80%以上。

7. 多搜索引擎要分开测试
Google接受URL参数处理,但ChatGPT和Perplexity不认。我优化了Google的重复页面后,发现AI引擎还是抓取带utm参数的版本。在robots.txt里用Disallow屏蔽掉所有带?的URL后,Perplexity引用率从12%涨到27%。

8. 预算有限时优先修canonical
月预算1-3万的情况下,别先砸钱做外链。我花2万块请人写guest post,结果Google先发现我内链结构混乱,重复页面太多,直接降权。花5000块找工具扫一遍canonical配置,修好了再搞内容。核子GEO的检测报告直接告诉我哪些URL在打架,省了60%排查时间。