有些蜘蛛池入口页为了防采集或者图省事,目标链接不写在 HTML 里,而是用 JavaScript 拼成字符串再插进页面。在浏览器里点开一切正常,但换成搜索蜘蛛来抓,这条发现路径会明显变长,甚至直接断掉。
抓取分两步:先取源码,再决定要不要渲染
搜索蜘蛛处理一个页面通常有两步:第一步是抓取,把服务器返回的 HTML 源码下载下来;第二步是渲染,把页面放进渲染队列执行 JS,拿到最终的 DOM。第一步里,它看到的只是一段 <script> 里的字符串,不是链接;只有走到第二步,链接才可能出现。
问题在于渲染队列的成本远高于普通抓取,优先级更低,等待时间从几小时到几天都有可能。对于入口页这种本身权重不高、又需要快速传递信号的页面,这个延迟会直接影响目标 URL 被发现的节奏。
不同搜索引擎的处理差别很大
- Google:渲染能力相对完整,但仍然要排队,且不保证每次都渲染。
- Bing:部分场景支持渲染,覆盖率不稳定。
- 百度:对 JS 渲染的支持有限,绝大多数情况下依赖源码里的链接。
- 其他中小引擎:基本只读源码,不做 JS 执行。
换句话说,把链接交给 JS,等于把发现权交给了对方“愿不愿意为你跑一次渲染”。这不是一个可以稳定依赖的前提。
几种典型的“写了等于没写”
- 用 innerHTML 把 <a> 标签拼进某个容器,源码里只有容器空壳。
- 链接没有真实 href,只绑了 onclick 事件做跳转。
- 页面先出骨架,链接靠接口返回后再异步插入,蜘蛛拿到的是空列表。
- 用 document.write 输出链接,容易在渲染阶段被覆盖或忽略。
- 链接放在 Shadow DOM 或闭包内部,渲染后也不一定暴露在可解析结构里。
这些写法在浏览器里肉眼可见,在源码里却搜不到目标 URL 的痕迹。入口页的职责本来就是把发现路径缩短,一旦把链接藏进 JS,反而多设了一道关卡。
noscript 不是可靠的兜底
有人会把链接主要放在 <noscript> 里,指望不渲染时能读到。实际效果并不稳定:部分引擎在开启渲染后就不再读取 noscript 内容,关闭渲染时又可能整段忽略。它最多算补充,不能当作主要通路来设计。
想保留 JS,也别让源码里没有链接
- 能服务端渲染就服务端渲染,把包含链接的最终 HTML 直接返回。
- 源码里至少保留一套静态 <a> 标签指向目标 URL,JS 只做体验增强。
- 链接使用真实 href,不要只靠点击事件跳转。
- 避免把入口页做成纯空壳,正文和链接先出,交互后加。
- 列表和翻页用普通超链接,不要让“加载更多”按钮成为唯一的入口。
怎么验证蜘蛛到底拿到没拿到
- 用搜索引擎提供的 URL 检查或渲染测试,查看渲染后的 HTML 里有没有目标链接。
- 翻服务器日志,确认搜索蜘蛛是否真的请求过目标 URL,而不是只抓了入口页。
- 把源码和渲染后的 DOM 对比,看链接是不是只存在于后者。
- 如果日志里目标 URL 长期没有任何抓取记录,优先怀疑渲染这一环,而不是去调内容。
一个很简单的自检:把页面源码单独复制出来,在里面搜一下目标 URL。如果搜不到,就不要默认搜索蜘蛛一定能发现它。
小结
JS 动态插入链接并非绝对无效,但它属于“多一道关卡”的方案,适合有充足抓取预算和渲染容忍度的站点。对蜘蛛池入口页这类以传递发现信号为主要任务的页面,能直出就直出,把 JavaScript 留给确实需要交互的部分,链接的发现率会稳得多。