入口偏移是什么样子
站点抓取日志里出现一批你从未设计过的地址:路径被拼接两次、目录名重复、或者带上多余的上级路径。这些地址往往还能正常打开,服务器命中了同一条规则返回 200,于是蜘蛛会反复来抓,真正需要被发现的页面反而被稀释。
它和 HTTP 重定向不是一回事。重定向发生在请求发出之后,而这里的问题发生在 HTML 解析阶段:蜘蛛读到的确实是你页面里的那个链接,但它按规则算出来的目标地址和你预期的不一样。
base 标签为什么容易出问题
base 标签会改变整页所有相对链接的解析基准。只要它写错一个层级,或者被前端脚本在运行时插入,页面上成百上千条链接会一起偏移。
三类高频写法问题
- base 的 href 本身写成相对路径,例如以 /sub/ 为基准,相对链接就会再拼一层,容易出现 /sub/sub/ 这类地址。
- 末尾斜杠缺失:带斜杠和不带斜杠的基准解析结果不同,前者把最后一段当目录,后者会把它当文件、退到父目录去算。
- 多份 base 或多个模板混用:同一个站里有的页面写了 base,有的没写,从同一个入口点进去,同一段相对链接会落到不同位置。
排查时先看服务器返回的原始 HTML,而不是浏览器里渲染后的 DOM。前端在运行时插入 base 的情况不少,你在控制台看到的和蜘蛛初次拿到的可能并不一致。
相对路径本身的坑
即使没有 base 标签,写法不统一也会造成偏移,常见的有几类:
- 使用一级相对写法,比如指向上一级目录的链接。页面一旦被搬到另一个层级,链接就指向别处。
- 链接中混入空格、全角斜杠、连续重复斜杠。部分服务器会归一化,部分不会,日志里就多出若干等价入口。
- 大小写不一致:在区分大小写的环境里,同一个页面会被当成两个地址,各自被单独抓取。
相对稳妥的做法是全站内链统一用站点绝对路径,也就是以斜杠开头,或者直接写完整域名。多打几个字符,换来的是一致性。
确认问题来自哪里
不要凭感觉改,先按下面顺序定位:
- 从日志里挑出五到十条陌生地址,记录它们被请求时对应的来源页。
- 用命令行抓取来源页的原始 HTML,搜索 base 标签以及出问题的那段链接原文。
- 手动按解析规则算一遍:基准地址加上链接原文,看结果是否与日志中的陌生地址一致。一致就基本锁定了。
- 再在渲染后的页面里核对一次,判断问题出在模板还是运行时脚本。
修复与观察
修改思路是从减少变量开始:
- 能不用 base 就不用;确实需要时,href 写成完整域名并带末尾斜杠。
- 内链改为站点绝对路径,避免各种相对的写法。
- 模板收敛,头部由一处生成,避免多套模板各写各的。
- 对已经产生的错误入口,用 301 指向正确页面,不要让它继续返回 200。
改完之后观察一到两周的抓取日志,重点看陌生地址的出现频次是否下降、目标页面的抓取次数是否回升。这个过程不会立刻见效,蜘蛛对旧地址的重访有一定惯性,但入口持续收敛,通常比反复提交地址清单更管用。
顺带核对两件事
一是站点地图与内链是否指向同一套地址,两套地址并存会让收敛效果打折;二是服务器是否会因为重复斜杠、大小写差异生成多个可访问副本。入口越干净,浪费在重复地址上的抓取资源就越少。