蜘蛛在站点上爬行时,不只是“发现新地址”这么简单,它还要判断哪些地址值得继续保留在队列里。很多站点的问题不是没有 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 指向保持一致,蜘蛛对站点的理解会逐步收敛。先处理暴露面最大的重复模式,再看日志验证,比一次性改全站更稳妥。