搜索抓取

同一页面被抓多次:URL 归一化怎么做

同一个内容页被蜘蛛用多条 URL 抓取,是很多站点都会遇到的情况。本文梳理大小写、末尾斜杠、协议与主机名、参数顺序、跟踪参数等常见的不一致写法,说明怎么从站内链接、服务端跳转和 canonical 三层做归一化,以及如何用日志与 Sitemap 验证收敛效果。

搜索抓取

同一页面被抓多次:URL 归一化怎么做

翻服务器日志时,很多运营者会发现一个现象:同一个内容页,被蜘蛛用好几条不同的 URL 抓过。抓取次数被摊薄,日志分析也跟着失真。这通常不是蜘蛛抓错了,而是站点自己给出了多个入口。

同一页面为什么会有多个 URL

常见的不一致写法大体集中在几类,先列出来对照自查:

  • 大小写不一致:/About 与 /about 都被返回 200。
  • 末尾斜杠:/list 与 /list/ 同时可访问。
  • 协议与主机名:http 与 https、带 www 与不带 www 并存,或改版后只跳了一半的链接。
  • 参数顺序与冗余参数:?a=1&b=2 与 ?b=2&a=1 被视为不同地址。
  • 跟踪参数:渠道、投放、会话类参数被写进了站内链接。
  • 编码差异:中文路径的百分号编码在大小写上不统一。

这些写法在浏览器里都能打开同一个页面,但对爬虫来说就是不同的 URL,会分别排队、分别抓取、分别判断内容。

先统一站内链接,再谈其他

内链是最直接的信号来源。导航、面包屑、列表页、相关推荐、Sitemap、RSS,只要其中一部分指向 A 写法、另一部分指向 B 写法,蜘蛛就会按两条 URL 处理。所以归一化第一步不是加标签,而是把站内所有出口统一成同一种写法。这一步做完,很多重复抓取会自然减少。

归一化的三层处理

  1. 入口层:模板、Sitemap、推送接口统一输出规范写法,避免新链接再次跑偏。
  2. 服务端层:对非规范写法做 301 到规范 URL,把历史链接和外部引用一起收拢。
  3. 页面层:用 canonical 声明首选版本,作为兜底手段。

301 与 canonical 不是二选一。能干净跳转的用 301;跳转不方便实现、或者需要保留访问参数的场景,用 canonical 指明首选版本。两者作用点不同,可以叠加使用。

参数怎么收敛

参数是最容易失控的一类。跟踪参数、排序参数、筛选参数、会话参数各自组合,能生成大量 URL。处理思路是先分类:影响内容的参数(筛选、排序)通常保留,但要让每个组合有可抓取的价值;不影响内容的参数(渠道、会话、来源标记)尽量在生成链接时就去掉,或在服务端做跳转剥离。不要用一刀切的方式屏蔽所有参数,否则会连同正常的分页、筛选一起拦掉。

怎么验证收敛效果

做完调整之后,用几个动作回看是否生效:

  • 按路径分组统计日志里的抓取次数,看是否还存在同一路径的多种写法。
  • 把自己爬一遍站内链接得到的 URL 集合,与 Sitemap 里的 URL 做对比。
  • 抽查页面的 canonical 是否自指、是否指向规范版本,避免指向一个会跳转的地址。
  • 观察一段时间内重复版本的抓取量是否下降。
归一化不是一次性工作。上线新模块、改版换模板、接入新的统计或投放参数时,都容易重新引入不一致的写法,需要定期回看。

目标其实很简单:把同一个内容收敛到一个 URL 上,减少没有意义的重复抓取,让有限的抓取机会留给真正需要更新的页面。做不到百分之百干净也没关系,先把量级最大的那几类写法处理掉,效果通常就出来了。