结论先说
把入口页的目标链接交给 JavaScript 生成,搜索蜘蛛能不能发现,取决于它会不会执行脚本、执行到什么程度、以及愿意等多久。写在静态 HTML 里的 a 标签链接是最稳的一类;由脚本拼出来再插入 DOM 的链接属于“有机会,但不保证”。在蜘蛛池这种靠页面数量换取 URL 发现的场景里,这个不确定性会被放大。
静态链接和脚本插入的链接,对蜘蛛意味着什么
搜索蜘蛛抓到一个入口页后,第一步是拿到 HTML。如果目标 URL 已经写在 HTML 里,它解析一次就能把链接全部收进待抓队列,成本很低。如果链接是页面加载后才由脚本拼出来、再插入到 DOM 里的,蜘蛛就得多做几件事:下载并执行脚本、等接口返回、等 DOM 发生变化,最后再从渲染后的页面里提取链接。这几步里任何一环失败或被跳过,链接就不会被发现。
换句话说,静态链接是“先有链接再有页面”,脚本链接是“先有页面再想办法变出链接”,两者的发现成本不在一个量级。
不同搜索引擎的处理能力不一样
主流引擎中,有一部分具备渲染能力,可以执行一部分 JavaScript;另一些主要看原始 HTML,渲染覆盖面和等待时间都比较有限。也就是说,同一份 JS 生成的入口页,在不同搜索引擎那里的发现率可能差出很多。做站点运营时如果只盯着某一家的表现,很容易误判整体效果。
另外,渲染本身是有预算的。渲染一个页面消耗的资源远高于解析静态 HTML,当入口页数量很多时,蜘蛛不会把渲染机会平均分给每一个页面,而是倾向于把资源留给它认为更值得的页面。
几种常见写法,风险并不相同
- 接口拉取后插入 DOM:链接来自异步请求,再通过 innerHTML 之类的方式写进页面。渲染能力强、接口响应快的引擎有机会拿到,但接口慢或超时就会整批漏掉。
- onclick 加 location.href 跳转:原始 HTML 里没有可以直接提取的地址,必须靠用户点击才会发生跳转。对蜘蛛来说约等于不存在,不适合作为唯一入口。
- 按钮或 div 绑定事件:同样缺少 href,发现概率更低。
- 脚本里以字符串形式保存 URL 列表:如果这些字符串没有变成真正的链接节点,即使脚本被执行,也未必会被当作可抓地址提取出来。
- 懒加载或点击后才加载:需要用户交互才出现的链接,蜘蛛通常看不到。
怎么自己检查
最直接的办法是对比两份内容:一份是查看网页源代码拿到的原始 HTML,另一份是浏览器里渲染完成后的 DOM。如果目标链接只出现在后者,说明它依赖脚本,发现率就打折扣。也可以借助搜索引擎提供的抓取测试工具,看它实际抓到的版本里有没有这些链接。
蜘蛛池场景下更稳妥的几条做法
- 入口页尽量做成静态 HTML,目标链接直接写在 a 标签的 href 里,一行一条,不依赖脚本。
- 数据必须动态化时,优先在服务端渲染好再输出,让最终返回的 HTML 里就带着链接。
- 纯前端渲染的页面,考虑预渲染或定期生成静态快照。
- 用 sitemap 或其他提交渠道做兜底,不要把 URL 发现的希望全压在一个 JS 入口页上。
- 控制单页链接数量,链接堆得越多,渲染与解析的负担越大,漏抓的概率也越高。
一个简单的判断标准:关掉浏览器的 JavaScript,或者只看原始 HTML,还能不能看到你想被发现的那些 URL。看不到,就别指望它稳定。
容易踩的几个误区
一是以为“我在浏览器里能看到,蜘蛛就能看到”。你打开页面时脚本早就跑完了,蜘蛛拿到的可能还是空壳。二是以为渲染机会是无限的,入口页越多越明显,实际上是有限的渲染预算被少数页面消耗掉。三是以为换哪个引擎结果都差不多,不同引擎对 JavaScript 的支持程度差别不小,最好分别观察,再决定入口页要做成什么形态。