先给结论:不要试图把两个版本“合并成一个真相”,而应把设备或登录状态当作内链策略的显式维度。做法是固定一个基准版本作为链接图的对照标准,再对差异版本单独记录链接差异;如果差异只出现在登录态,优先检查内链是否被服务端按会话裁剪,而不是先怀疑抓取工具出错。
假设你对一个栏目页做内链审计:桌面端未登录访问时,页面正文里有 12 个站内链接;换到移动端模拟或登录后再看,只剩 7 个。两种结果都来自同一个地址,但链接图不同,后续的“哪些页面没被内链指向”的判断就会跟着变。
这类差异不一定是故障。它可能来自响应式布局里被折叠的导航、按登录角色渲染的推荐模块,也可能是缓存把某个版本返回给了另一类请求。问题在于:如果你不先确认差异属于哪一类,就会把两种版本的链接混在一张表里,得出错误的内链缺口。
第一种解释是渲染差异。服务端返回的 HTML 基本相同,链接差异来自 CSS 隐藏、脚本延迟插入或客户端按视口宽度改写 DOM。此时原始 HTML 里的链接可能都在,只是可见性和可点击性不同。
第二种解释是服务端条件返回。服务端根据 User-Agent、Cookie、登录态或地域,直接输出不同的 HTML。此时链接差异在响应体里就已经存在,与浏览器怎么渲染无关。
两种解释对应完全不同的内链策略动作。若是渲染差异,内链本身存在,重点转向“这些链接是否可被稳定发现”;若是服务端条件返回,重点转向“基准版本是谁、差异版本要不要纳入链接图”。
区分动作很具体:对同一个地址,分别用桌面 UA 未登录、移动 UA 未登录、桌面 UA 已登录三种条件请求,保存原始 HTML,而不是只保存渲染后的截图或 DOM。然后做两步比对。
<a href>,统计数量和目标地址。如果三种条件的原始 HTML 链接集合一致,差异只出现在渲染后的可见集合,那更接近渲染差异。如果原始 HTML 的链接集合本身就不同,那就是服务端条件返回,设备或登录状态已经进入了内链生成逻辑。
这里有一个容易误判的点:请求量或抓取量在某个条件下变少,不能单独证明该版本被正确排除。它也可能来自缓存命中、请求频率限制、日志采样或工具本身的重试策略。要把它当作线索,而不是结论。
两种做法都成立,取决于你的内链策略要服务谁。
以未登录桌面版为基准,适合内容型站点:主要目标是让公开可发现的内链结构保持稳定,登录态和移动端只做补充验证。代价是会漏掉只在登录后出现的内链模块,如果这些模块承担了重要的权重或路径引导,基准图就不完整。
为每个版本各建一张链接图,适合功能型站点或会员内容占比较高的站点:不同角色看到的内链本来就有意义,分开记录才能判断“某个页面是否只在登录后被链接”。代价是维护成本上升,任何内链改动都要在多个版本上同步核对,否则会出现版本间漂移。
选择条件可以简化成一句:如果登录态内链只是个性化推荐,用基准版即可;如果登录态内链是到达某些页面的唯一路径,就必须单独建图。
假设一个内容站有 500 个详情页,你怀疑移动端少了一批相关阅读内链。可以这样走:
<a href> 指向站内详情页的部分,忽略导航、页脚等全站重复链接。如果“仅移动版出现”的链接集中在某个模块,而该模块在桌面版原始 HTML 里根本不存在,说明服务端按设备输出了不同内链。下一步不是立刻改模板,而是先确认这个模块是否承担了必要路径:如果它只是补充推荐,可以把它排除在基准图之外;如果它指向的页面没有其他内链入口,就要考虑在基准版里补一条稳定路径。
这个动作的结果会直接决定下一步:差异被归为渲染问题时,你改的是可见性和可发现性;差异被归为服务端条件返回时,你改的是基准版本的选择和链接图的边界。两者不能混着改,否则对照结果会再次失真。
最后提醒一点:robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录。设备或登录态返回不同内容时,真正需要先锁定的是“哪个版本的原始 HTML 被当作内链策略的依据”,其余判断都应建立在这个基准之上。