站内能被发现的地址数量,和页面上写了多少链接不是一回事。如果链接是在浏览器里由 JavaScript 生成之后才出现的,搜索蜘蛛要先拿到页面、执行脚本、等渲染完成,才可能看到这些地址。这一步能不能走通,取决于渲染方式和页面结构。
原始 HTML 与渲染后的 DOM 不是一回事
搜索蜘蛛抓取一个页面时,最先拿到的是服务器直接返回的 HTML 源码。多数情况下,链接是从这份源码里被提取出来,进入待抓取队列的。如果源码里只有一段脚本占位,真正的链接要等脚本执行完才出现,这些链接的发现就多了一道关卡:需要渲染。
渲染并非不可行,但它有前提:脚本要能正常加载、接口要能正常返回、页面要能在合理时间内渲染完成。任何一环卡住,链接都可能看不到。相比之下,直接写在 HTML 里、带 href 属性的 a 标签,是最稳定的信号。
判断标准很简单:在不执行脚本的情况下查看页面源代码,能不能看到目标链接的地址。能看到,这条链接基本不依赖渲染;看不到,就要评估渲染环节是否可靠,以及有没有其他入口补上。
三种渲染方式对 URL 发现的影响
服务端渲染
服务器在返回 HTML 之前就把内容拼好,链接以 a 标签形式出现在源码里。蜘蛛拿到的第一份响应就包含导航、列表和分页地址,不需要额外等待。对 URL 发现来说,这是最省事的做法。
静态生成与预渲染
页面在构建阶段生成 HTML,链接同样写在源码里,适合栏目页、文章页这类数量可枚举的内容。需要注意的是新发布的地址是否及时重新生成,否则新链接不会出现在任何一份 HTML 中,只能靠 Sitemap 或其他入口补上。
纯客户端渲染
HTML 里几乎是空壳,链接全部由脚本生成。这种情况下,URL 发现依赖渲染队列的调度,速度更慢,也不保证每个页面都能渲染成功。常见的折中做法是给关键导航和列表页做服务端渲染或预渲染,只把交互性强的部分留给客户端。
内链结构里最该检查的几个位置
- 主导航与页脚:用 a 标签输出真实地址,避免用点击事件或脚本跳转代替。
- 面包屑:它既是抓取路径,也是层级关系的说明,尽量静态输出。
- 列表页与分页:新地址大多从这里进入抓取队列,分页链接要能直接点到。
- 相关推荐与聚合入口:如果由接口异步加载,至少保证页面上有一份可读的链接兜底。
怎么自查
- 禁用脚本打开页面,看导航和列表里是否还有可点的链接。
- 查看源代码,搜索 href 出现的次数,和页面上实际链接数对比。
- 用抓取测试工具查看渲染后的结果,对比渲染前后链接数量的差异。
- 在服务器日志里确认蜘蛛是否请求过某个新地址。如果它连请求都没有,问题多半出在发现环节,而不是抓取环节。
几个容易踩的坑
- 用带 # 的 hash 路由做导航,蜘蛛看到的往往是同一个地址,无法区分不同内容。
- 脚本里拼接的相对路径大小写与真实地址不一致,产生大量重复或失效地址。
- 渲染超时或接口报错,页面停在加载状态,链接既没被发现,也没有明确报错。
- 把链接写成按钮,样式上像链接,语义上只是可点击元素。
可爬性应该排在渲染方案之前考虑:先保证链接能静态输出,再决定哪些部分交给脚本。
如果站内确实有一部分链接只能由脚本生成,也不必完全否定,但要给这些地址留第二条通道:在 Sitemap 里申报、在关键位置补静态入口、在日志里盯住它们是否被请求。URL 发现不是一次性的工作,渲染方式变了、模板改版了,发现路径也会跟着变。定期把源码和日志对一遍,比等到收录出问题再回头排查要省事得多。