做蜘蛛池或站内入口頁时,很多人只關心連結放没放上去,却忽略了連結地址最终被解析成什么。相對路径和 base 标簽都會改變這一点:源碼里寫的是 a/b,蜘蛛請求的可能是另一個地址。
相對路径以目前頁面地址為基准解析
搜尋蜘蛛拿到 HTML 後,會按 URL 标准把相對路径拼成绝對地址,基准是入口頁自身的最终 URL,也就是经過跳轉之後真正返回内容的那一個。举例:入口頁地址是 https://example.com/list/index.html,頁面里寫 href="detail/1.html",解析结果是 https://example.com/list/detail/1.html;如果寫成 /detail/1.html,則解析為 https://example.com/detail/1.html。
容易出错的是目錄和文件的混淆。入口頁地址是 https://example.com/list 而没有末尾斜杠,相對路径 detail/1.html 會被解析成 https://example.com/detail/1.html,不是 /list/detail/1.html。這個差异會直接让蜘蛛請求到 404,或者抓到另一個不相關的頁面。
base 标簽會整体改寫解析基准
如果入口頁 head 里寫了 base href,指向例如 https://example.com/other/,那么頁面上所有相對連結都會以這個地址為基准,而不是目前頁面地址,蜘蛛一般會遵守這個規則。這时頁面里寫 href="1.html",蜘蛛請求的就是 https://example.com/other/1.html。
几個细节值得注意:
- 規范只認第一個 base href,後面出現的通常會被忽略;
- base 寫在 head 之外、或寫在連結之後,不同解析器的處理可能不一致,最好统一放在 head 靠前位置;
- base 只影响相對 URL,绝對 URL 和以井号開头的锚点連結不受影响;
- 协议相對寫法如 //cdn.example.com/x 會繼承目前頁面的协议,http 頁面里就是 http。
哪些寫法最容易出問题
- 相對路径省掉前導斜杠,靠目錄层級猜位置,解析结果和预期不同;
- 入口頁存在跳轉,基准變成跳轉後的地址,相對路径随之改變;
- 同一批入口頁放在不同目錄,模板里寫的是相對路径,结果指向了不同頁面;
- 連結里带空格、中文、特殊符号没有做 URL 编碼,蜘蛛請求的是编碼後的形式;
- 把 base 当成统一前缀批量复用,忘了它對頁面上所有相對連結都生效。
怎么核對蜘蛛實际請求的地址
- 浏览器打開入口頁,用開發者工具選中連結,看 DOM 里 a 元素 href 属性的解析结果,而不是源碼里寫的值;
- 查看服務器日誌中蜘蛛對入口頁的請求,以及随後對哪些路径發起了請求,對比是否與预期一致;
- 用抓取工具或本地脚本解析 HTML,輸出每個連結解析後的绝對 URL,批量检查;
- 把入口頁和模板里的相對路径尽量改成绝對路径,尤其是跨目錄、多子域的场景。
相對路径和 base 标簽属于解析层的問题,連結本身有效,只是解析结果和预期不同。先把這一步核對清楚,再去讨论抓取和收錄。
一点實践建议
入口頁數量多、模板复用时,最省心的做法是連結统一寫绝對地址,或者至少统一加前導斜杠。如果必须用 base,就把它固定寫在 head 最前面,並在測試环境確認解析结果。
蜘蛛發現 URL 只是第一步,能否被抓取、會不會被索引,還取决于頁面返回狀態、内容质量和站点整体情况。遇到路径對不上时,先看日誌里蜘蛛請求了什么,比反复調整入口頁更有效率。