canonical 到底在解决什么問题
同一段正文,常常因為 URL 寫法不同而變成好几個地址:带 www 和不带 www、http 和 https、结尾有没有斜杠、參數顺序不同、大小寫不同、移動版單獨挂在另一個域名下……對用戶来说這是一個頁面,對爬虫来说這是多個 URL。canonical 的作用就是明确告诉蜘蛛:這一组地址里,哪一個才是應该保留的主版本。
它不阻止抓取,也不保證替換索引,只是尽量把重复信号收敛到主版本上,减少抓取预算被浪費在變体地址上。
最容易漏掉的重复来源
- 协议與域名變体:http 與 https、www 與裸域同时可訪問。
- 末尾斜杠與大小寫:/about 與 /About/ 返回同一份内容。
- 跟踪參數:utm_ 系列、from=、ref= 等只是渠道标识,却生成了新 URL。
- 站内搜尋结果頁與篩選頁:颜色、價格区間、排序方式组合出的地址。
- 打印頁、AMP 頁、單獨拆出来的移動版。
- 分頁列表:第一頁與不带頁碼的地址其實是两份正文。
自查时按這個顺序做
- 先用站内搜尋或抓取工具,找出标题、正文高度相似但 URL 不同的一组组地址。
- 每组挑一個“最该保留”的地址:可讀性好、有内鏈指向、有稳定訪問。
- 在其余變体頁面的 head 里加 rel="canonical",寫绝對地址,並确保目标能返回 200。
- 主版本自己也要寫一條指向自身的 canonical,避免解析时找不到明确信号。
- 同组内的内鏈统一指向主版本,不要一邊声明 canonical,一邊大量鏈向變体。
提醒:canonical 是建议而不是命令。当頁面内容差异過大、指向目标明顯不相關,或者目标頁返回 404、被 robots 拦住、被 noindex,蜘蛛很可能直接忽略這條声明。
常见的寫错方式
- canonical 指向重定向鏈中間或末端的 404 地址。
- 同一個頁面出現多條互相矛盾的 canonical。
- 用 JS 動態插入 canonical,首屏 HTML 里根本没有這條标簽。
- canonical 與 hreflang 打架:語言版本之間應互相指向並各自自指,不要全部 canonical 到某一個語言版。
- 用 canonical 把内容差异很大的頁面强行合並,试图“借權重”。
- 分頁场景下把第 N 頁 canonical 回第一頁,却没给用戶和蜘蛛留下繼續翻頁的路径。
上线後怎么驗證
改完不要只看一眼頁面源碼就收工,更實用的做法是:
- 用抓取工具批量抓取目标 URL 组,检查狀態碼、canonical 字段和頁面标题是否一致。
- 看日誌里這些地址的抓取频次是否逐步向主版本集中,變体地址是否慢慢减少。
- 观察索引中保留的版本,若變体仍被收錄,回头检查内鏈、Sitemap 或站内搜尋是否還在产出變体地址。
- 把 canonical 規則寫進模板,而不是靠人工逐頁补,避免新頁面又漏掉。
和 robots、noindex 的分工
這三者经常被混用:robots.txt 是“不要来抓”,noindex 是“可以抓但不要收”,canonical 是“可以抓可以收,但請以這一份為准”。用错會出現“想合並却把頁面挡在门外”,或者“想屏蔽却被持續抓取、白耗预算”。先想清楚目的,再决定用哪一個。
最後补一句:canonical 只能减少内部重复,解决不了内容本身的問题。如果變体頁面确實有獨立價值,更合理的做法是把它做成有獨立标题、獨立结构的頁面,而不是硬合並到別處。