canonical 标签:28 个首页 23 个声明了,其中三个声明的是我们被路由过去的那一页

canonical 标签实测:30 个站的首页,28 个读得到,23 个声明了 canonical,没有一个和实际下发的地址矛盾。但其中三个声明的是地理跳转之后的那个语言页。

抓取与收录5 分钟读完2245 次阅读
canonical 标签:28 个首页 23 个声明了,其中三个声明的是我们被路由过去的那一页

实测 · 2026-08-19 · 30 个站 · 单次快照

样本与口径:与我们此前 robots.txt、sitemap、首页结构、请求链四轮实测同一批 30 个站。每个站首页请求一次,浏览器 UA,跟随跳转,2026-08-19,出口在日本大阪。两个站拒绝了我们,所以分母是 28。

28 个首页里有 23 个声明了 canonical 标签,而且这 23 个声明的地址,和我们实际拿到的那个地址一模一样,一个矛盾都没有。没声明的 5 个是 nextjs.org、supabase.com、reddit、Hacker News 和 wikipedia.org。真正值得带走的不是「都一致」这个结论,是其中三个「一致」到的那个地址是什么。

怎么测的

口径在跑之前就定死了,跑完没改。

  1. 用桌面浏览器 UA 请求一次 https://<域名>/,跟随跳转,记下最终地址。
  2. 把下发的 <head> 里每一个 <link rel="canonical">href 和个数都记下来。
  3. 忽略末尾斜杠,把 canonical 和最终地址做比较。

不渲染,不执行 JavaScript。前端注入的 canonical 我们数不到,这对用这种方式实现的站是一条实打实的局限。

23 个有,5 个没有

这个分法不是随机的。没有 canonical 的 5 个里,两个是开发者平台、两个是社区站、一个是维基百科的入口页——都不是那种「重复地址会成问题」的页面。

分组个数是哪些
有,且与下发地址一致23样本里其余的站
有,但与下发地址矛盾0
完全没有5nextjs.org、supabase.com、reddit、Hacker News、wikipedia.org
首页拒绝了请求2stackoverflow.com(403)、medium.com(403)

Google 明确推荐自引用这种写法:We recommend adding this same self-referential rel="canonical" link element to the canonical page itself as well.(我们建议在规范页面自己身上也加上这条指向自身的 canonical。)23 个站是这么做的。剩下 5 个没有也不算缺陷——Google 把这条声明当强信号,不当硬性要求,没有它照样会挑一个规范地址出来。本篇引用的 Google 原文都是 2026-08-19 在 developers.google.com 那份讲规范化的文档里读的。

三个站的 canonical,是我们被路由过去的那个地址

这是本篇最该带走的一条。我们的请求从日本出口,所以这 23 个里有三个 canonical,并不是一个美国访客会看到的那个。

站点我们请求的读到的 canonical
stripe.comhttps://stripe.com/https://stripe.com/en-jp
slack.comhttps://slack.com/https://slack.com/intl/ja-jp
developer.mozilla.orghttps://developer.mozilla.org/https://developer.mozilla.org/en-US/

三个站都是先把我们跳走,再把落地的那一页声明成规范地址。对那一页来说这是对的。而这恰恰就是全部的问题:爬虫从一个固定的地方出口,不会换个地方再试一次。它被路由到哪儿,哪儿就成了它眼里你首页的地址。

做出海的话,这条直接对着你

用 IP 判断访客国家、然后跳到对应语言或对应市场的落地页,是独立站上最常见的做法之一。它对真人有用,对爬虫是替它做了选择。你想让 Google 收录的那个版本,和它实际拿到的那个版本,可能从来不是同一个。

Google 讲多语言时指向的是另一套机制:for canonicalization purposes Google prefers URLs that are part of hreflang clusters(在确定规范地址时,Google 更倾向于处在 hreflang 组里的 URL)。同一页还提醒,语言信息本身不会由 canonical 承载:rel="canonical" annotations with hreflang, lang, media, and type attributes are not used for canonicalization.(带 hreflang、lang、media、type 属性的 canonical 声明不用于规范化。)所以语言分发要靠 hreflang 声明清楚,不能靠「访客是从哪儿来的」去暗示。

在地理跳转之后算出来的 canonical,描述的是你被送去的那一页,不是你要的那一页。

末尾斜杠几乎对半开

23 个 canonical 里 12 个以斜杠结尾、11 个不带。两组各自都和自己站上实际下发的地址一致,也就是说两组内部都是自洽的,这里没有一个可以照抄的惯例。

还撞见一次主机名变更:我们请求的是裸域 figma.com,拿到的是 https://www.figma.com/,canonical 写的也是后者。这是归并在正常工作,也是整个样本里唯一一处 canonical 在干实事、而不是在复述显而易见的事。

BBC 把同一个 canonical 发了两遍

两个 <link rel="canonical">href 完全相同,连框架属性都一样。看起来是 head 里重复输出了一条,不是两条互相打架,而且因为指向同一个地址,搜索引擎这边没有什么要裁决的。

两个 href 不同的 canonical 会怎样,我们不知道。Google 讲规范化的那份文档没有涉及这种情况,我们也没有构造测试去验。知道「文档在这件事上是沉默的」,比假设存在某条规则要好。

你自己的 canonical 标签该怎么办

两个该做的,两个别做的。

  • 从当前正在下发的这次请求去拼 canonical,不要从存下来的字段拼。这里所有的失效方式,起点都是一个记着旧值的模板。
  • 用绝对地址。Google 支持相对路径,同时明说 they can cause problems in the long run(长期看它们会带来麻烦)。
  • 别让地理跳转决定你的 canonical。语言版本用 hreflang 声明,canonical 只负责描述这一页。
  • 一个页面别发两个 canonical,哪怕内容一样。没有可以依赖的公开行为。

下结论之前,先从公司网络之外拉一次自己的首页——你在国内登录着看到的那个版本,不一定是爬虫拿到的那个版本。爬虫到底够不够得着、读不读得到你的页面,可以用AI 爬虫可达性检查器先过一遍。

真要动手改地址时该先锁住什么、改写会连带砸坏哪几处,在301跳转之外还会砸坏什么那篇。同一批站里有几个把语言版本声明清楚了,在hreflang 到底有几个站在声明那篇。

常见问题

你们是怎么测的

2026-08-19,每个站首页请求一次,桌面浏览器 UA,跟随跳转,出口在日本。从下发的 HTML head 里读 canonical,忽略末尾斜杠和最终地址做比较。不渲染。

首页需要 canonical 标签吗

不是必须。Google 推荐加一个自引用的,并把它当强信号;本样本里有 5 个站一个都没发。真正要紧的场合,是确实存在重复地址的时候。

canonical 该不该带末尾斜杠

跟你实际下发的地址保持一致就行。本样本里 23 个中 12 个带、11 个不带,两组都和自己的站对得上。

canonical 能解决内容重复吗

它告诉搜索引擎你偏好哪个地址。它不会让另一个地址消失,而且它是信号不是指令,所以两个页面在抢同一件事这个问题,仍然要你自己去做决定。

从美国出口的爬虫读到的会一样吗

至少这三个站不一样。它会读到什么,我们答不了——这次只从一个位置跑了一遍。

canonical 标签:28 个首页 23 个声明了,其中三个声明的是我们被路由过去的那一页