翻站点日誌时经常會看到這样的画面:同一篇文章的 URL 以好几種形態出現,蜘蛛挨個抓了一遍,返回的都是 200,正文也几乎一样。表面上看抓取次數很漂亮,實际上被覆盖的頁面並没有增加,只是把有限的抓取次數摊薄在了重复地址上。URL 去重属于那種平时没人管、出問题时又很难一眼看出来的基础工作。
蜘蛛按 URL 区分頁面,不按内容
抓取系統排队、判重、分配回訪频率,第一步依據的都是 URL 字符串。只要字符串不同,它就是两個待抓地址;至于打開之後内容是否相同,那是抓回来之後才判断的事。所以對服務器来说,凡是能返回 200 的地址,都會被当成一個獨立頁面去消耗抓取资源。真正需要做的,是让同一篇内容在對外暴露的地址上尽量只有一個。
常见的重复来源
- 域名层:带 www 與不带 www、http 與 https 同时可訪問,且没有强制跳轉。
- 大小寫:/Article/123 與 /article/123 都能打開,部分服務器环境确實区分大小寫。
- 结尾斜杠:/list 與 /list/ 返回同一頁。
- 預設文件:/about 與 /about/index.html 並存。
- 端口号:外鏈里混進了 :80、:443 這類預設端口寫法。
- 跟踪參數:?utm_source=、?from=、?spm= 等,同一篇文章被外部轉發出多個地址。
- 排序與篩選:列表頁的 ?order=、?sort= 组合出大量内容相近的頁面。
- 會话與临时 ID:URL 里带 sessionid、随机 token。
- 分頁:?page=1 與不带參數的第一頁内容一致。
這些情况單獨看都不嚴重,凑在一起就足以让一個中小站点多出几倍的待抓地址。
先確認是不是真重复,再决定怎么處理
不要只凭 URL 長得像就動手合並。先抓下来對比三样東西:标题、主要正文、對外声明的規范地址(canonical)。如果正文主体完全不同,那它是獨立頁面,不该被 301;如果只是參數不同、正文一致,才属于要去重的對象。比較稳妥的方式是拿日誌里出現频次最高的那批地址,人工抽几十條核對一遍,再决定規則。
處理顺序:從源头到兜底
- 先统一下發的連結。站内導航、面包屑、列表頁、Sitemap 里輸出的地址必须是同一個形態。内鏈是蜘蛛最主要的入口,内鏈自己就不统一,後面怎么补救都費劲。
- 用 301 做强制归一。把 http 跳 https、非 www 跳 www、大寫跳小寫、带預設端口跳标准形態。跳轉要一步到位,不要串成多級跳轉。
- canonical 做兜底。對于參數頁、打印頁這類不方便直接 301 的地址,用 canonical 指向主地址,帮助判重。注意 canonical 與 301 的指向要一致,否則等于给蜘蛛两個相反的答案。
- Sitemap 只放規范地址。站点地图里混入重复地址,等于主動把重复 URL 送到蜘蛛面前。
- 參數處理要克制。排序、篩選參數如果确實产生了有價值的獨立頁面,就让它正常被抓;如果只是同一批内容換了個顺序,考虑限制其抓取,而不是全部 301 回首頁。
几個容易踩的坑
- 把所有參數頁 301 到首頁或栏目首頁,容易被当成不当跳轉,反而影响判断。
- 301 鏈太長:A 跳 B、B 跳 C,蜘蛛每跳一次都要重新發起請求,成本叠加。
- 只改内鏈不做跳轉:老地址仍能從外鏈、歷史快照、用戶收藏進入,重复地址依然存在。
- 把 robots.txt 屏蔽重复地址当作去重手段。屏蔽只是不让抓,地址仍然存在,也不利于權重传递,不如老老實實做跳轉。
- CDN 或反向代理层做了大小寫归一,源站没有,两邊規則不一致时會来回跳。
去重的目标不是让日誌里的 URL 變少,而是让每一個被抓的地址都對應一個真實、獨立的頁面。
怎么確認有没有做干净
改完之後隔一段時間回到日誌里看两件事:一是同一路径下大小寫、斜杠、參數的變体請求量是否明顯下降;二是 301 是否集中在少數几條規則上。如果仍然有大量變体被以 200 返回,說明源头還没堵住——多半是内鏈或者外部引用仍在往外吐舊形態的地址。内鏈统一、跳轉到位、Sitemap 干净,這三件事做完,抓取次數才算花在了该花的地方。