投喂之前把 URL 過一遍,几乎每個做蜘蛛池的人都會做,但多數人只做了一件事:看這個地址能不能打開。存活檢測筛掉的是打不開的地址,筛不掉的是另一類問题——同一個目标頁,往往能用好几種寫法落進入口頁。http 與 https、带 www 與不带 www、结尾有没有斜杠、參數顺序換個位置,在浏览器里打開都是同一頁,在抓取系統的帳本里却是好几條不同的 URL。
這件事為什么值得單獨處理
入口頁上的連結就是蜘蛛的路线图。如果同一批目标被寫成三四種形態,入口頁的可点击連結數會被撑大,但真正指向的内容並没有變多。带来的直接结果是:入口頁看起来“很丰富”,實际有效线索密度變低;池子里的抓取請求有相当一部分落到了重复地址上;日誌里同一目标的抓取记錄被拆散,你很难從數字上判断某個 URL 到底被抓了几次。
更麻烦的是後續判断。做冷啟動或者調量的时候,很多人是看日誌里的抓取條數来判断池子狀態的。重复地址混在里面,條數是虚高的,真實覆盖的目标數被高估,後面加量、减量的决策就會失准。
常见的几種“看着不一样其實一样”
协议與主机名
- http:// 與 https:// 寫成两條
- 带 www 與不带 www 各寫一條
- 用 IP 直接訪問與用域名訪問混着用
這几種在入口頁里最容易被無意中混進来,尤其是從不同来源抓地址拼列表时。建议在投喂前统一到一個形態,通常是站点對外主推的那個版本。
尾斜杠與路径寫法
- /page 與 /page/ 同时存在
- /a/./b 與 /a/b
- 路径里出現连續斜杠 //
尾斜杠是否等價取决于服務器怎么處理,有的站点两者都返回 200,頁面對蜘蛛来说就是两份。既然不确定,就別把两種都寫進去。
大小寫與编碼
路径部分在多數服務器上是区分大小寫的,但參數名、參數值经常不是。同一個中文關鍵詞,UTF-8 编碼和 GBK 编碼出来的地址完全不同,百分号大小寫(%2F 與 %2f)也可能被判成两條。這類地址如果在入口頁里同时出現,除了制造重复,還會让蜘蛛抓到一组内容相同的頁面。
參數顺序與無意义參數
- ?a=1&b=2 與 ?b=2&a=1
- 带 utm_、from、spm、ref 之類的来源标记
- 带會话 ID、時間戳、随机數
来源标记和會话參數對頁面内容没有影响,属于典型该清掉的部分。參數顺序不同但在服務端被忽略的那種,也建议在投喂前统一。
去重放在哪一步
比較顺的顺序是三段:先做归一化,再做存活檢測,最後做去重。
- 归一化:统一协议、主机名、大小寫、尾斜杠、编碼方式,剔除無關參數。這一步只做字符串處理,不請求目标站,成本很低。
- 存活檢測:對归一化之後的地址發請求,看狀態碼和响應内容。這一步才有網絡開销,放在归一化之後能少發很多無用請求。
- 去重:按归一化後的完整地址做精确比對,也可以對去掉參數後的路径做一层模糊比對,避免同一個頁面換個參數又被当成新地址。
顺序反了會怎样:先存活檢測再归一化,等于對同一個頁面反复發請求;先存活檢測再归一化再存活檢測,就更没必要了。
同一目标保留几條地址合适
多數情况下,一個目标頁對應一條地址就够了。入口頁需要的是明确的线索,不是同一线索的多個副本。下面几種情况可以考虑保留多條:
- 目标站确實同时對外提供 http 和 https,且两者内容獨立可訪問
- 移動版與桌面版是两套獨立地址,並且你打算分別投喂
- 目标頁有明确的參數化形式(例如分類篩選頁),内容和預設頁不同
除此之外,同一目标在入口頁里出現多次,基本只是在稀释入口頁的連結價值,同时让你後面對日誌的分析變难。
几個容易踩的坑
- 只看狀態碼不看内容:有些站点對不存在的地址也返回 200,配一個提示頁。归一化能减少這類地址的生成,但不能替代内容层面的判断。
- 去重粒度太粗:只按域名去重,會把同域下的不同頁面当成一條;只按完整地址去重,參數一變又漏了。
- 归一化規則前後不一致:第一周按不带 www 處理,第三周換成带 www,歷史日誌和現在的資料就對不上了。規則一旦定下来,最好寫進流程里固定住。
- 把去重当成收錄保障:去重只解决入口頁自身的清晰度問题,抓不抓、收不收由目标站和搜尋引擎决定,這两件事不要混着看。
落地建议
给入口頁做一張固定的處理規則表,把协议、主机名、尾斜杠、大小寫、參數白名單這些寫清楚,每次投喂前按同一套規則跑一遍。同时保留一份原始地址和归一化後地址的對照,出問题时能回溯是哪一步改的。規則稳定之後,入口頁的連結數、日誌里的抓取條數才有可比性,後面判断池子狀態、調整投喂量才有意义。