常见问题

入口页的链接由 JavaScript 动态生成:搜索蜘蛛能发现这些 URL 吗

入口页的目标链接如果是脚本跑起来之后才出现的,搜索蜘蛛能不能发现,取决于它是否执行 JavaScript、渲染预算够不够、以及愿意等多久。本文对比静态链接与脚本插入链接的差别,梳理几种常见写法的风险,并给出蜘蛛池场景下更稳妥的入口页做法。

常见问题

入口页的链接由 JavaScript 动态生成:搜索蜘蛛能发现这些 URL 吗

结论先说

把入口页的目标链接交给 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。如果目标链接只出现在后者,说明它依赖脚本,发现率就打折扣。也可以借助搜索引擎提供的抓取测试工具,看它实际抓到的版本里有没有这些链接。

蜘蛛池场景下更稳妥的几条做法

  1. 入口页尽量做成静态 HTML,目标链接直接写在 a 标签的 href 里,一行一条,不依赖脚本。
  2. 数据必须动态化时,优先在服务端渲染好再输出,让最终返回的 HTML 里就带着链接。
  3. 纯前端渲染的页面,考虑预渲染或定期生成静态快照。
  4. 用 sitemap 或其他提交渠道做兜底,不要把 URL 发现的希望全压在一个 JS 入口页上。
  5. 控制单页链接数量,链接堆得越多,渲染与解析的负担越大,漏抓的概率也越高。
一个简单的判断标准:关掉浏览器的 JavaScript,或者只看原始 HTML,还能不能看到你想被发现的那些 URL。看不到,就别指望它稳定。

容易踩的几个误区

一是以为“我在浏览器里能看到,蜘蛛就能看到”。你打开页面时脚本早就跑完了,蜘蛛拿到的可能还是空壳。二是以为渲染机会是无限的,入口页越多越明显,实际上是有限的渲染预算被少数页面消耗掉。三是以为换哪个引擎结果都差不多,不同引擎对 JavaScript 的支持程度差别不小,最好分别观察,再决定入口页要做成什么形态。