蜘蛛在站点上爬行时,不只是“發現新地址”這么简單,它還要判断哪些地址值得繼續保留在队列里。很多站点的問题不是没有 URL,而是同一份内容對應了太多 URL:带排序參數的列表頁、加跟踪參數的分享連結、大小寫不同的路径、结尾斜杠變体。它們都能返回 200,蜘蛛就可能分別排队、分別抓取。canonical 标簽是用来收敛這些重复地址的常见工具,但它不是開關,也不能阻止蜘蛛訪問。
重复 URL 簇通常從哪里来
先看几個常见来源。多數重复不是刻意制造,而是功能设計和統計需求自然产生的。
參數與篩選组合
篩選、排序、分頁、價格区間、视图切換,每個參數都能生成新 URL。如果站内連結直接輸出這些參數组合,蜘蛛會沿着連結一路展開,形成大量内容相近的頁面。更麻烦的是參數顺序不同(?a=1&b=2 與 ?b=2&a=1)也可能被当成两個地址。
會话與跟踪參數
為統計来源、广告投放、用戶會话附加的參數,如果服務端不處理,就會進入 URL。蜘蛛通常不會带會话,但站内連結、分享按钮、外部引用可能把带參數的版本暴露出来。這些 URL 返回正常頁面,就會被当作可抓取地址。
路径细节變体
结尾斜杠、大小寫、URL 编碼、預設文档路径(/index.html)等,如果服務器不做统一跳轉,同一内容會有多個入口。蜘蛛對每個入口都可能單獨记錄。
canonical 能做什么,不能做什么
canonical 的作用是告诉搜尋引擎:這一组相似 URL 中,哪個是規范版本。它影响的是归並和展示選擇,不是抓取许可。蜘蛛仍然可能抓取非規范 URL,尤其在它們被内鏈、sitemap 或外鏈大量指向时。
- 它是提示,不是指令。搜尋引擎可能忽略冲突或不可信的 canonical。
- 不阻止抓取。要减少抓取,需要從連結暴露、robots、跳轉等层面處理。
- 需要一致。canonical 指向的頁面應当可訪問、返回 200、内容對應,不要指向 404、重定向鏈或多层跳轉後的地址。
- 不要互指。多個頁面互相 canonical,通常等于没有明确規范。
- 不要指向被屏蔽的 URL。如果規范頁被 robots.txt 屏蔽或带 noindex,信号會互相矛盾。
把 canonical 当成“归並提示”,而不是“抓取開關”,很多排查思路會清晰很多。
让抓取更集中在規范 URL 上
目标不是让蜘蛛完全不看重复地址,而是减少無意义地址的暴露面,让队列優先處理規范頁和重要頁。
- 内鏈只指向規范版本。導航、面包屑、列表頁、頁脚、相關推荐,尽量輸出统一格式的 URL。
- Sitemap 只列規范 URL。不要把带參數、带會话、排序篩選的變体放進 sitemap,否則等于主動提交重复地址。
- 用 301 合並永久重复。大小寫、斜杠、舊路径這類确定性重复,跳轉比 canonical 更直接。
- 處理無意义參數。對排序、跟踪、會话參數可以统一跳轉、忽略或按需屏蔽;但不要誤伤带實际内容篩選的 URL。
- 分頁規范指向自身。分頁第 2 頁、第 3 頁通常應 canonical 到自身,而不是第一頁,否則可能让蜘蛛不再抓取後續列表。
- 避免無限组合。篩選參數不要任意叠加,必要时限制可選组合或對無结果组合返回 404/410。
一個简單的排查顺序
- 從抓取日誌里找出高频訪問的重复 URL 模式,看參數、斜杠、大小寫、路径层級。
- 確認這些 URL 是否出現在内鏈、sitemap、分享模板或外部引用中。
- 检查頁面 canonical 是否指向正确規范頁,規范頁是否可訪問且未被屏蔽。
- 對确定性重复做 301,對參數變体做统一處理,對無價值地址考虑屏蔽或移除入口。
- 改完後观察日誌中重复模式的占比是否下降,規范頁抓取是否更稳定。
容易踩的几個坑
- canonical 寫到另一個語言版本,導致語言信号混乱;多語言站点應配合 hreflang。
- canonical 指向 noindex 頁面,等于把規范信号送给一個不被索引的地址。
- 用 JavaScript 動態插入 canonical,蜘蛛渲染时机不同,可能看不到。
- 只加 canonical,却繼續在内鏈里大量輸出參數 URL,抓取队列依舊被占满。
- 把 canonical 当成 301 使用,舊地址繼續返回 200,蜘蛛仍會反复訪問。
重复 URL 簇不會一夜之間消失,但只要入口、sitemap、跳轉和 canonical 指向保持一致,蜘蛛對站点的理解會逐步收敛。先處理暴露面最大的重复模式,再看日誌驗證,比一次性改全站更稳妥。