你的站有 /blog/、/blog/page/2/、/blog/page/3/。Search Console 在 page 2+ 标 “Duplicate, Google chose different canonical”。老 SEO 文章让你把每个分页页的 canonical 都指向 /blog/,或者加 rel="prev" / rel="next"。新文章说反过来。两边都过时了一半。
最快的修法: 让每个分页页自指 canonical(/blog/page/2/ 的 canonical 指向 /blog/page/2/,而不是 /blog/),分页链接保留成真实的 <a href> 锚点,只对真正低价值的变体(搜索结果、faceted filter 组合)用 noindex, follow。这正是 Google 自己文档现在的说法——“Don’t use the first page of a paginated sequence as the canonical page. Instead, give each page its own canonical URL”(分页最佳实践,Google Search Central)。
Google 在 2019 年停止使用 rel=next/prev,之后建议一直没变。下面是诊断和逐步实现。
先判断你属于哪一类
改任何东西之前,先看分页页实际发出的 canonical,并确定它是哪种页面。
| 你观察到的现象 | 诊断 | 修法 |
|---|---|---|
page/2/ 的 canonical 指向 /blog/ | 老的”canonical 到 page 1”做法(最常见) | 改成自指 canonical(第 2 步) |
page/2/ 既有 noindex 又在 sitemap 里 | 信号矛盾,Google 两个都不信 | 二选一:可索引 + 自指 canonical,或 noindex + 从 sitemap 移除(第 4 步) |
URL 是 ?page=2&sort=date&filter=ai | 参数排列看起来像重复 | 真实列表自指 canonical,filter/sort 变体 noindex(第 4 步) |
URL 只因某个过滤组合存在(?tag=ai&page=2) | 是 faceted filter 视图,不是真正分页 | noindex, follow(第 4 步) |
| 滚动加载内容但 URL 一直不变 | 无限滚动、没有可爬的 URL 状态 | 加真实分页 URL + sitemap(第 5-6 步) |
| 已经自指 canonical 但还是被标 | 多半是报告延迟,不是真错 | 用 URL 检查核实(见”如何确认已修好”) |
直接读 canonical:
curl -s https://yoursite.com/blog/page/2/ | grep -i 'rel="canonical"'
常见原因
按命中率从高到低。
1. 老教程说 page/2 → page/1 canonical
2019 年前的建议是把每个分页页都 canonical 到 page 1。现代 Google 把这个解读为你在声明”这些不是真实页面——给我看 page 1”,于是 page 2-N 的内容基本掉出索引。Google 现在的文档明确说这是错的:每页要有自己的 canonical。
怎么判断:看 /blog/page/2/ 的 <link rel="canonical">。指向 /blog/ 就是按老建议做的。
2. 还在发 rel=next/prev(通常无害)
Google 自 2019 年起忽略 rel=next/prev,所以它对 Google 排名没任何作用。它们也不会有害,而且 Bing 和部分搜索引擎仍会读——Yoast 就是为此故意继续发它们。只有在你想让标记更干净时才删;不要把它们的存在当成 bug。
怎么判断:curl -s https://yoursite.com/blog/page/2/ | grep -E 'rel="next"|rel="prev"'。有也没关系,它不是重复标记的成因。
3. 分页页有 noindex + sitemap 冲突
有些模板给分页加 noindex 并 把它留在 sitemap.xml,造成 Robots meta 与 sitemap 冲突 里描述的矛盾。Google 看到一个信号说”别索引”,另一个说”这是重要 URL”。
怎么判断:view-source 分页页。如果有 noindex 且同一 URL 又出现在 sitemap.xml 里,就解决这个冲突。
4. 分页用 URL 参数 Google 分不清
/blog?page=2&sort=date&filter=ai——没有 canonical 指引时,Google 的启发式可能把这些排列当重复,爬虫也会在每个低价值组合上浪费预算。
怎么判断:分页靠 query string 参数(尤其多个同时出现),而不是 /page/2/ 这样干净的路径分段。
5. 分页内容确实是重复(过滤视图)
/blog/?tag=ai、/blog/?tag=ai&page=2 等。每个组合是唯一 URL,但页面只是过滤已有列表。这些应该 noindex, follow。
怎么判断:分页 URL 只是因为某个过滤组合而存在,而不是因为你的内容库本身深到需要翻页。
6. 无限滚动、没有可爬的 URL 状态
无限滚动 listing 通过 JavaScript 加载更多项但 URL 始终不变,Google 没法触达更深的项。(相关但略有不同的问题。)
怎么判断:滚动加载更多项但 URL 一直停在 /blog/。Google 只索引它在初始 HTML 里看到的第一批。
最短修复路径
第 1 步:按分页类型决定
| 分页类型 | 处理 |
|---|---|
主博客索引分页(/blog/page/2/) | 每页 self-canonical,可索引 |
| 分类 / 标签分页 | self-canonical,可索引 |
| 搜索结果 | noindex, follow |
| Faceted filter 组合 | noindex, follow,或在 robots.txt 里拦掉该模式 |
| 无限滚动 | 并行补上真实分页 URL,并列进 sitemap |
第 2 步:博客 / 分类分页改成 self-canonical
每个分页 URL 的 canonical 指向它自己。
Astro:
---
const url = new URL(Astro.url.pathname, Astro.site).toString();
---
<link rel="canonical" href={url} />
/blog/page/2/ 的 canonical → /blog/page/2/。完成。
WordPress / Yoast 默认就这么做——分页归档页会自指 canonical,所以你通常只需确认某个插件或主题没把 canonical 又改回 page 1。
第 3 步:rel=next/prev 留或删都行
Google 两种情况都不用它们。在意 Bing 就留着;想要更干净的标记就删掉。它们不是重复标记的成因,所以除非你在整理模板,否则别在这里花时间。
- <link rel="next" href={`/blog/page/${currentPage + 1}/`} />
- <link rel="prev" href={`/blog/page/${currentPage - 1}/`} />
第 4 步:只对真正低价值的变体 noindex
对搜索结果、排序、过滤组合,用 robots meta 标签——这正是 Google 自己对”同一列表的各种变体”的建议:
<meta name="robots" content="noindex, follow">
follow 很重要——Google 仍要跟内链发现可索引内容。如果一个 URL 是 noindex,也要把它从 sitemap.xml 移除,免得犯原因 3 里那种信号矛盾。
第 5 步:确保分页可爬
分页链接必须是真实的 <a href> 锚点,不能只是 JavaScript 按钮。Google 的渲染预算可能不执行 JS 分页,深层页会发现不了。
<a href="/blog/page/2/">下一页</a>
Google 还建议让每一页都链回第一页,以强化整个集合的起点。
第 6 步:sitemap 里列出分页 URL
把 /blog/、/blog/page/2/、/blog/page/3/ … 都作为独立条目,帮 Google 发现深层分页。对无限滚动来说,这份 sitemap(或商品 feed)正是 Google 推荐的主要发现路径。
非常深的分页(超过约 30 页)时,再建可浏览的分类 / 标签 listing,让深文章离首页的点击路径更短。
第 7 步:修后审 Search Console
Search Console → Pages → 看分页 URL 的状态。Google 重新抓取后,约 2-4 周内应从 “Duplicate, Google chose different canonical” 移到 “Indexed”。
如何确认已修好
- 实时 URL 检查:在 Search Console 里对
/blog/page/2/跑 URL Inspection,点 “Test Live URL”,确认 “User-declared canonical” 和 “Google-selected canonical” 现在都显示/blog/page/2/。 - 重看原始标签:
curl -s https://yoursite.com/blog/page/2/ | grep -i 'rel="canonical"'应该返回该页自己的 URL。 - 观察报告变化:Pages 报告里 “Duplicate, Google chose different canonical” 的计数会在接下来几个抓取周期下降。
截至 2026 年 6 月,有一点值得知道:Google 的 Martin Splitt 在 2025 年指出,被这样标记的 URL 仍可能作为近重复聚类(near-duplicate cluster)的成员留在 Google 索引里,即便 GSC 报告显示它未被索引。所以如果页面是自指 canonical、返回 200、并有内链,它大概率没问题——这个标签会滞后于实际情况。不要为了”修好”这个标签而把 canonical 又指回 page 1。
常见问题
每个分页页应该自指 canonical,还是 canonical 到 page 1? 自指。Google 现在的文档说得很直白:别把 page 1 当作整个系列的 canonical;给每页自己的 canonical URL。
删掉 rel=next/prev 能修好我的重复 canonical 标记吗?
不能。Google 自 2019 年起就忽略这些标签,所以它既不是成因也不是修法。这个标记来自你的 canonical(或 noindex/sitemap)信号,而不是 rel=next/prev。
“Duplicate, Google chose different canonical” 真的在伤害我吗? 不一定。它表示 Google 选了和你声明不同的 canonical。如果你的分页页是自指 canonical、返回 200、有内链,这个状态常常只是报告假象,页面仍可能在索引里。只有当真实列表页被并进 page 1 时才需要修。
我该不该把所有分页页都 noindex,免得吃重复内容惩罚?
不该——合法分页没有重复内容惩罚,而对真实列表页 noindex 会把它们链向的文章一起藏起来。只对低价值变体用 noindex, follow:搜索结果、排序、faceted filter 组合。
我的分页用 ?page=2 参数,必须换成 /page/2/ 路径吗?
不是必须,但干净的路径分段更便于 Google 当作不同页面处理。如果你继续用参数,就让每个参数页自指 canonical,并对 filter/sort 排列 noindex,免得爬虫在重复页上浪费预算。
多久 Search Console 会显示页面已 Indexed? 通常 Google 重新抓取后 2-4 周。可以对最重要的分页页用 URL Inspection 请求索引,加快首次重新抓取。
预防建议
- 每个分页页当独立 listing——self-canonical、可索引。
- 别把
rel=next/prev当修法;Google 忽略它们(只为 Bing 而保留)。 - 对过滤 / 搜索结果变体用
noindex, follow——绝不完全拦掉,否则 Google 发现不了它们背后的内容。 - 分页用真实
<a>链接,不要只用 JS 按钮。 - 把
noindex的 URL 排除在 sitemap 之外,避免发出矛盾信号。 - 加新 listing 类型时重新审计分页行为。