很多抓取問题里,頁面本身能返回 200,内容也正常,但蜘蛛拿到的那批連結却指向了错誤的主机或路径。這類情况通常不是服務器配置引起的,而是 HTML 中相對連結與 base 标簽的解析结果,和运营的预期不一致。
蜘蛛如何把連結變成绝對地址
解析 HTML 时,蜘蛛會按标准 URI 引用規則,把 href 里的相對引用與「基准 URL」拼接。基准 URL 預設是目前文档地址;一旦文档里出現 base 标簽,就會改用 base 指定的地址。常见几種形態:
- 绝對連結(https://example.com/a)不受基准影响;
- 根相對連結(/a)會替換基准的路径部分;
- 路径相對連結(a 或 ../a)基于基准的目錄拼接;
- 协议相對連結(//example.com/a)沿用目前頁面的协议。
也就是说,基准 URL 一變,頁面上所有相對連結的落点都會跟着變。
base 标簽的常见誤用
全站模板里统一寫死 base
有些站点為了兼容舊系統,在模板 head 里放了一條固定的 base,例如指向測試域名或另一個子域。蜘蛛從正式域名抓到的頁面里,相對連結會被整体拼到那個域名下,正式站的内鏈结构在抓取视角里等于断裂。
base 带路径却漏了结尾斜杠
base href="https://example.com/blog" 與 base href="https://example.com/blog/" 的结果完全不同。前者會把頁面里的 a 拼成 https://example.com/a,後者才是 https://example.com/blog/a。這類偏差在目錄型站点里很隐蔽,因為浏览器地址栏看不出異常。
多個 base 或位置靠後
規范要求只取文档中第一個 base 的 href。有些頁面在公共模板和组件里各寫了一條,實际生效的未必是运营以為的那條。另外,如果 base 出現在 head 之後,不同解析器對已讀内容的處理並不完全一致。
其他容易造成落点偏差的寫法
- 相對連結寫在 JS 拼接的字符串里,静態 HTML 中拿不到,也就形不成入口;
- 連結寫成 //example.com/a,頁面在 http 與 https 之間切換时,落点协议會跟着變;
- href 前後夹带空格、換行或不可见字符,部分解析器會直接丢弃;
- 用 <a href="#"> 配合 onclick 跳轉,蜘蛛只會看到一個指向目前頁的锚点。
怎么排查
- 從日誌里挑出被抓取频繁的頁面,把 HTML 原样儲存下来;
- 用标准解析库(如 Python 的 urljoin 配合解析器)重新計算頁面里每個 href 的绝對地址;
- 把结果與 Sitemap、内鏈清單交叉比對,看是否存在落到非目标域名或集中 404 的路径;
- 同时检查服務器日誌里,是否有蜘蛛在請求一個你並不打算公開的域名或目錄。
如果日誌里出現集中請求某個測試域名的情况,基本可以判断是基准 URL 出了問题,而不是網絡抖動或封禁。
修复與長期维護
- 能用绝對連結的地方尽量用绝對連結,尤其是導航、面包屑、頁脚這類模板区域;
- 确實需要 base 时,统一在 head 最前面寫一條,路径结尾带上斜杠,並在發布前做一次回归检查;
- 把 base 标簽、站点主域名、Sitemap 中的域名纳入同一份上线检查清單;
- 站点改版或迁移域名後,重新跑一遍比對流程,避免舊 base 跟着模板被留下来。
相對連結本身没有問题,問题在于基准 URL 是否和你的运营意图一致。基准错了,頁面内容再完整,蜘蛛拿到的仍然是一張指错方向的連結图。