先弄清楚:同一份内容為什么會有多個地址
蜘蛛抓取时看到的不是「頁面」,而是一個個 URL。同一份内容落在多個 URL 上,抓取請求就被分摊到這些地址里,日誌里看起来像每個地址都抓了一点,但哪個都没抓透。常见来源有:
- 协议與主机名不统一:http 與 https、带 www 與不带 www 同时可訪問。
- 大小寫與尾斜杠:/Page 與 /page、/list 與 /list/ 各自返回 200。
- 跟踪參數:渠道来源參數、會话參數、广告点击 ID 被带進了内鏈。
- 排序與视图參數:?sort=、?view=、?page=1 與不带參數时返回的内容一致。
- 功能頁複製:打印頁、導出頁、獨立移動版地址。
- 多域名指向同一套站:备用域名、測試域名没有做訪問限制。
這些地址如果都能返回 200,蜘蛛就會各自排队;如果其中一部分被 robots.txt 屏蔽,問题會變成「抓了但抓不到内容」,排查起来更绕。
蜘蛛在多個地址之間怎么挑
没有一個自動去重的開關。蜘蛛看到多個候選地址时,會综合几個信号来挑選主地址,從强到弱大致是:
- 301 跳轉:服務器直接指向唯一地址,信号最明确。
- rel=canonical:頁面自己声明主地址,属于提示性质。
- Sitemap 里的寫法:站点地图给出的地址通常被当成站方認可的主入口。
- 内鏈與導航:站内連結大多數指向哪個寫法,蜘蛛更倾向沿用哪個。
- 外部引用:外站連結指向的版本會被当作參考。
麻烦在于這些信号经常互相矛盾:canonical 指向 A、内鏈大量指向 B、Sitemap 里寫的是 C。冲突时蜘蛛只能自己選,结果往往不是你想要的那一個。
用日誌核對三件事
- 統計每個重复地址的抓取次數與返回狀態碼,看是否出現两個地址被平均抓取的分流現象。
- 看抓取入口從哪来:是 Sitemap、内鏈還是外鏈,找到把舊寫法扩散出去的源头。
- 抽几個地址對比返回内容,確認還是同一份内容,還是已经出現了分叉。
收敛顺序:把改動放在信号最强的地方
先做服務器层,再做頁面层,最後清内鏈。顺序反了,改動容易被舊信号抵消。
- 统一协议與主机名:确定一個主地址,其余用 301 永久跳轉,尽量不要用 302 或 JS 跳轉。
- 規范大小寫與尾斜杠:让服務器只認一個寫法,其余一律 301,不要两種寫法都返回 200。
- 頁面内 canonical 指向主地址,使用绝對地址,不要指向自身以外的重复頁。
- 過滤參數:能被内鏈生成的參數尽量去掉;必须带參數的頁面,让它 canonical 到無參數版本,或做其他處理,二選一,別同时做。
- 清理站内連結:導航、面包屑、列表頁模板里的地址寫法统一,尤其是模板批量生成的内鏈。
- Sitemap 只留主地址,把重复地址從地图里剔除。
canonical 是提示而非指令,301 才是硬信号。能用跳轉解决的,不要只寫一行 canonical 就收工。
几個容易踩的坑
- canonical 指向一個被 robots.txt 屏蔽的地址,等于把信号送進了黑洞。
- 分頁的第 1 頁 canonical 指向無參數版本,第 2 頁及以後也全部指向第 1 頁,深层内容會被從抓取路径里切断。
- 用 canonical 把別家的内容指到自己站,短期看着舒服,實际是典型的错誤做法。
- 測試域名没有做訪問限制,蜘蛛抓到了两份几乎一样的站点。
改完之後看什么
改動上线後,別急着盯收錄數量,先看日誌里的抓取分布:重复地址的抓取次數應当逐步下降,主地址的抓取次數上升;Sitemap 中上报的地址與實际被抓取的地址應当逐渐一致。這個收敛過程通常要几周到一两個月,期間要保證内鏈和 Sitemap 不再生成舊寫法,否則又會被拉回去。