先理解一件事:搜尋蜘蛛看到的是字符串,不是頁面
搜尋蜘蛛在决定要不要抓一個 URL 之前,處理的對象是一串字符,而不是你脑子里的那個頁面。所以同一個目标頁,只要在入口頁里被寫成两種不同的字符串,就存在被当作两個 URL 记錄、两次抓取的可能。
它确實會先做一轮基础規范化,把明顯等價的寫法合並掉。但這轮規范化有邊界,邊界之外的差异會被原样保留。入口頁的連結寫法不统一,浪費的正是這部分:抓取次數花掉了,覆盖的却還是同一個頁面。
搜尋蜘蛛通常會自動處理哪些差异
下面這些差异,一般在抓取前就會被归一,不會各自成為獨立 URL:
- 协议與主机名的大小寫,例如 HTTP://Example.com 會被当作 http://example.com;
- 預設端口,:80 和 :443 通常會被去掉;
- URL 里的 #片段,片段不會發送给服務器,一般不參與区分;
- 相對路径,會被解析成完整的绝對地址;
- 部分多余的轉义字符。
注意,這一层只是格式上的合並,不涉及内容判断。它不會去分析两個地址返回的 HTML 是否一样。
哪些差异通常會變成两個 URL
下面這些差异,搜尋蜘蛛一般不會替你合並,會当成不同地址分別進入待抓取队列:
- 路径大小寫:/Page 與 /page。多數 Linux 服務器区分大小寫,确實可能是两個资源,搜尋蜘蛛没有理由假设它們相同;
- 结尾斜杠:/a 與 /a/。服務器可能返回 200、也可能返回 301,搜尋蜘蛛只能按响應判断;
- 跟踪參數:?utm_source=x 與 ?utm_source=y,值不同就是不同字符串;
- 參數顺序:?a=1&b=2 與 ?b=2&a=1,字符串不同;
- 預設文档:/ 與 /index.html;
- 协议與 www:http 與 https、带 www 與不带 www,只要服務器没有强制跳轉,就是三四個地址。
對蜘蛛池入口頁意味着什么
入口頁的作用是让目标 URL 被看见。如果同一條目标 URL 在入口頁里以參數、大小寫、斜杠混着寫,日誌上會顯得抓取量不小,但去重之後可能只覆盖一個頁面。抓取配額被切碎,真正需要被發現的其它 URL 反而排在後面。
更麻烦的是統計失真。按原始 URL 統計,你會以為覆盖了 200 個地址;按規范化後的地址归並,可能只有 60 個。
實际操作上可以這样收敛
- 给每條目标 URL 定一個規范形態,统一大小寫、统一是否带结尾斜杠、统一是否带 www 和协议,之後所有入口頁只寫這一種。
- 服務器端做 301 收敛。把 /a/、/A、/index.html 這類變体统一跳到規范地址,這是最有效的一步,因為搜尋蜘蛛最终會跟随到同一個落点。
- 頁面里加 canonical,指向規范地址,作為服務器跳轉的补充。
- 入口頁尽量不带跟踪參數。統計需求可以通過日誌或服務器端埋点解决,不必寫進連結。
- sitemap、内鏈、外鏈寫法保持一致,只要有一處不一致,就多一條待抓取记錄。
規范化是站点自己该做的事。搜尋蜘蛛只负责按字符串抓取和按响應判断,它不會因為"你觉得這是同一個頁面"就替你合並。
怎么驗證有没有做到位
几個成本不高的检查方式:
- 取一段日誌,按規范化後的路径分组,看同一路径出現了几種原始寫法;
- 手動訪問變体地址,看返回的是 200 還是 301,跳向哪里;
- 在搜尋控制台里看已收錄地址,是否出現同頁多地址的情况;
- 改動後隔一段時間再抽样,確認變体寫法在减少。
小结
入口頁里 URL 寫法不统一,通常不會让頁面打不開,但會让 URL 發現的效果打折。先把規范形態定下来,再用 301、canonical 和统一的内鏈寫法把變体收敛掉,日誌看起来會更清楚,抓取也更集中。
另外提醒一句:不要反過来刻意制造變体,指望"地址多就覆盖广"。變体带来的是重复抓取,不是更多的有效覆盖。