做蜘蛛池的人常把精力放在内容、模板和域名上,却很少回头看一件更基础的事:蜘蛛是先看到 URL,再决定要不要抓的。同一個頁面,如果服務器允许它同时以 /Page、/page、/page/、/page?from=abc 四種形態返回 200,那么在蜘蛛眼里這就不是一條地址,而是四條。抓取预算没有變,能用来發現新連結的次數却先少了一截。
URL 形態先于内容被判断
蜘蛛的調度队列里存的是 URL,不是頁面。去重、排期、回訪频率,都建立在 URL 這一层。内容完全相同的两頁,只要地址不同,蜘蛛就得各自抓一次才能確認它們是不是一样。對站点規模不大的普通站,這点损耗可以忽略;對批量生成入口頁的蜘蛛池,它會按模板产量成倍放大。
大小寫與结尾斜杠:同一頁面,多種寫法
- 路径大小寫:/List 與 /list 在多數服務器上是两條 URL,除非系統做過统一處理。
- 结尾斜杠:/page 與 /page/ 常被当成两個地址,返回的内容却一模一样。
- 預設文件:/page、/page/、/page/index.html 同时可達,等于给蜘蛛開了三條入口。
- 协议與主机名:http 與 https、带 www 與不带 www,若没有 301,會各自累积各自的记錄。
這些變体單看都不致命。麻烦在于入口頁是模板批量出来的,模板里只要有一處没收敛,所有頁面都會带上同样的毛病。日誌里看着蜘蛛来訪量不低,實际覆盖到的獨立地址却不多,這就是典型症状。
查询參數是最容易失控的一段
排序、篩選、分頁、来源跟踪,這些參數往往能無限组合,落地内容却只有一份。蜘蛛顺着站内連結往下爬,很快會撞上大量内容相同、URL 不同的地址。更糟的是參數可能被外部連結带進来,你甚至不知道蜘蛛是從哪條路径爬進這堆地址的。
處理思路大致分三层:
- 能静態化就静態化,把篩選和排序尽量放在前端交互里,不让它生成新的 URL。
- 确實需要參數的,用 robots 規則或服務端逻辑限制组合爆炸的入口,只放行必要的參數形態。
- 對已经存在的重复形態,用 301 把舊形態收拢到主版本,再用 canonical 做补充說明。
canonical 是给蜘蛛的提示,不是命令。真正起作用的,還是服務器不要用 200 把同一份内容發到很多條 URL 上。
動態 URL 與伪静態
伪静態不是必须的,但它能把參數形態固定下来。如果入口頁本来就由程序按 ID 生成,把 ?id=123 改寫成 /p/123.html 這類稳定形式,至少让地址的總量是可枚举的,而不是随參數组合飘移。要注意的是:改寫之後舊形態仍可能被外部引用,所以 301 要一起做,否則只是多了一套地址。
一份可以落地的检查清單
- 列出入口頁模板可能产生的全部 URL 變体,包括大小寫、斜杠、預設文件、协议與主机名。
- 為每種资源确定唯一形態,其余形態统一 301 到它。
- 抽查服務器返回碼,確認變体没有全部返回 200。
- 翻訪問日誌,統計蜘蛛抓到的 URL 里有多少是同一内容的重复形態。
- 模板每次改動後重跑一遍,別只在建池时检查一次。
把路修平,不承诺结果
URL 形態不是玄学,它是蜘蛛認识一個站点的第一层信息。把這一层收干净,抓取预算才更可能花在真正需要被發現的新地址上。至于最终是否收錄、收錄多少,仍取决于内容质量與站点整体狀態,規范化只是把路修平,不能替你把车開到终点。