Product Schema 评论数与页面可见评论对不上

JSON-LD 报 1,247 条评论、4.8 星,页面上只有 32 条。Google 判定为内容不一致,SERP 里的星级片段直接消失。

你的商品页之前在 SERP 上一直挂着五星片段。上周片段消失了,页面看起来什么都没改。Search Console 在 Products 报告里安静地标了一个 “Mismatched review” 警告。view-source 一看就明白:aggregateRating 声明 1,247 条评论、4.8 星,而页面”评论”区只有数据库里的 32 条。Google 在这里规则很硬 —— 你在 JSON-LD 里声明的每一条评论 / 评分都必须在同一个页面上对用户可见。跨站评论数、第三方插件、“全球”汇总,全都违反这条规则。

常见原因

按真实团队踩坑频率排序。

1. 全站汇总的评分被声明在单页上

你的平台把全部门店、市场、地区的评分汇成一个全球数字,模板再把这个全球数字声明在每一个商品页上 —— 而每个页面其实只显示自己那部分评论。

怎么判断:几十个互不相关的商品页 reviewCount 都是同一个数。可见评论只是这个数的一小部分。

2. 评论靠第三方插件展示,JSON-LD 来自另一份数据

可见评论由 Yotpo / Trustpilot / Bazaarvoice 之类的插件加载。页面上的 JSON-LD 是服务端从你自己的数据库生成的。两边永远对不上。

怎么判断:禁掉 JavaScript 刷新一次。可见评论数掉到 0,但 JSON-LD 还在报几百条 —— 说明插件是可见评论的唯一来源。

3. 站外评论被算进了 aggregateRating

Amazon、Google Shopping、合作伙伴站点的评论被合并进了汇总。它们不在 Google 抓取的这个页面上,所以 Google 拒绝这个评分。

怎么判断:评论系统有”包含外部来源”开关并且开着。关掉,重算,跟 JSON-LD 输出比对。

4. 缓存过期:可见评论已更新,JSON-LD 还是旧的

评论被审核删除,可见数下降。JSON-LD 生成器把 reviewCount 缓存了 24 小时,依然报删除前的数字。

怎么判断reviewCount 跟昨天一模一样。可见数已经降了。缓存 TTL 刚好对得上时间差。

5. 多规格商品,每个 SKU 都声明同一个汇总评分

母商品有 6 个尺寸 / 颜色规格。每个规格页都声明母商品的汇总评分(1,247 条),但页面上只显示自己那一份(比如 18 条)。

怎么判断:所有规格 reviewCount 都一样。可见数每个规格不同。

6. bestRating / worstRating 把量纲写错了

JSON-LD 写的是 10 分制("bestRating": "10"),可见评论却是 5 分制。Google 把 4.8 解读成 4.8/10,星级片段直接掉到很低。

怎么判断:可见 UI 写 “4.8 / 5”,JSON-LD 却是 "bestRating": "10"

开始前

  • 改动之前先截一张 SERP 富结果的基线截图。修完之后用来对比。
  • 看 Search Console → Enhancements → Products 那里是 “Invalid items” 还是只是 warnings。
  • 列出页面上所有可能产出评论数据的组件:服务端 JSON-LD、第三方插件、microdata、RDFa。
  • 确定真相来源 —— 通常跟可见插件用同一份。

需要收集的信息

  • 原始 HTML 里的 reviewCountratingValuebestRatingworstRating 具体值。
  • JavaScript 完全渲染之后页面上的可见评论数。
  • 可见评论的来源系统(Yotpo、Trustpilot、自研数据库等)。
  • 多规格页面是共用一段 schema 还是每个规格一段。
  • Search Console 上原文警告字符串的截图。

一步步修

按性价比排序。

第 1 步:用直接对比确认存在不一致

curl -s https://example.com/products/widget | \
  grep -oE '"reviewCount":\s*"?[0-9]+"?' | head -1

把这个数和页面上能看到的数对比。差距超过四舍五入,就是这个 bug。

第 2 步:确定唯一真相来源

下决定:你是想让 JSON-LD 镜像用户在页面上看到的内容,还是想露出你的全球汇总?Google 要求前者。挑驱动可见插件的那个来源,让 JSON-LD 走同一个调用。

第 3 步:把跨源汇总从 schema 里去掉

// before — 把所有平台都汇进来
const reviewCount = totalReviewsAcrossPlatforms(productId);

// after — 只算这一页上真的渲染出来的评论
const reviewCount = visibleReviewsOnPage(productId, locale, variant);

可见插件显示 32 条,reviewCount 就必须是 32。

第 4 步:让规格页各自归位

规格页把 schema 限定到这个规格:

{
  "@type": "Product",
  "name": "Widget — Red, Large",
  "sku": "WID-RED-L",
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.7",
    "reviewCount": "18",
    "bestRating": "5",
    "worstRating": "1"
  }
}

每个规格 URL 只挂自己的汇总。如果某个规格一条评论都没有,整段 aggregateRating 去掉,不要 fallback 到母商品。

第 5 步:把评分量纲锁死

明确写 bestRatingworstRating,跟可见 UI 一致。消费类评论大多是 5 分制:

"aggregateRating": {
  "@type": "AggregateRating",
  "ratingValue": "4.8",
  "reviewCount": "32",
  "bestRating": "5",
  "worstRating": "1"
}

第 6 步:评论变化时让缓存失效

把 JSON-LD 缓存 key 绑到一个内容版本号,审核或新增评论时这个版本号翻动。光靠短 TTL 不够 —— 24 小时 TTL 就意味着最多一天的过期富结果。

第 7 步:重新验证并请求再次索引

  • 在修好的 URL 上跑 Rich Results Test;确认 aggregateRating 没有 “mismatched review” 警告。
  • 对 5-10 个核心商品 URL 走 URL Inspection → Request indexing。
  • 盯 Search Console “Products” 增强报告;2-4 周内 warning 会逐步退出。

验证

  • Rich Results Test 报告 “Valid”,aggregateRating 上没有 warning。
  • 页面可见评论数与 JSON-LD 里的 reviewCount 完全一致。
  • 2-4 周内星级片段重新出现在 SERP 上(在 Search Console 跟踪展示数)。
  • 规格页各自挂自己的汇总,不再被母商品的数字带跑。

长期预防

  • 在团队范围明确写下规则:“JSON-LD 里出现的每一个数字都必须在同一个页面上可见。”
  • schema 里的评论字段要从驱动可见插件的同一个 API 拉 —— 永远不从单独的”全球”来源拉。
  • 加一个 CI 断言:抽样爬一批商品页,比较 JSON-LD 的 reviewCount 与可见数。
  • 有站外评论的站点不要把跨域评分汇成一个页面级 schema;要么单独引用,要么干脆不挂。
  • schema 生成器内建规格意识,永远不让母商品评分泄漏到子 URL 上。

常见坑

  • 把热门规格的评论”借”给长尾规格,让它看起来有口碑 —— Google 能识别重复,整个产品线都会被标。
  • ratingValue 写两位小数,但可见 UI 只显示一位(“4.85” vs “4.9”)。精度要跟可见的一模一样。
  • 评论全部被审核删掉之后还留着 aggregateRatingreviewCount 是 0 就整段拿掉。
  • 把站内”点赞 / 点踩”控件算作评论。Google 要求是真实的评论文本。
  • 写虚构的 bestRating / worstRating,例如 10 或 100,而可见量纲是 5。Google 会重新解释评分,显示一个很低的分。

FAQ

Q:我能把全球评论数放在别的地方展示吗,比如”全店超 1,200 条评论”?

可以 —— 作为页面正文的散文写出来就行,不要进 aggregateRating。Schema 必须镜像同一个页面上的内容。文案里吹总数,schema 保持诚实。

Q:修完之后星级片段多久回归?

通常 2-4 周。Google 在抓取时重新评估结构化数据;高流量商品 URL 重抓最快。在收入最高的页面上申请索引可以加速。

Q:我们每个页面只有 4 条评论。还要不要挂 aggregateRating

Google 要求至少 1 条评论,对小样本(小于 5 条左右)不鼓励,因为缺乏统计意义。低于 5 条就别挂 schema,让页面在没星级片段的情况下竞争。

Q:我能不能用 iframe 内嵌 Trustpilot 的评论片段?

评论必须在同一页面上、用可抓取的 HTML。iframe 里的内容不属于父页面。要么把评论文本服务端渲染出来,要么不要在 schema 里声明这些评论。

标签: #SEO #排查 #结构化数据 #product-schema #aggregaterating