常见问题

入口页的链接由 JavaScript 动态生成:搜索蜘蛛到底能发现多少

入口页里的链接如果是 JavaScript 现场生成的,浏览器能看到不代表搜索蜘蛛能看到。本文说明静态 a 标签、noscript、JS 数组循环、异步接口这几种写法的实际差别,以及怎么用日志判断链接有没有被纳入抓取队列,并给出几条减少漏抓的调整思路。

常见问题

入口页的链接由 JavaScript 动态生成:搜索蜘蛛到底能发现多少

入口页的作用是让搜索蜘蛛顺着链接继续走,但如果这些链接是 JavaScript 现场拼出来的,情况就复杂了。很多人遇到过同样的现象:用浏览器打开一切正常,日志里却看不到蜘蛛来抓那批新 URL。这一篇把常见写法和它们的实际表现讲清楚。

先接受一个前提:不同搜索蜘蛛的 JS 能力差别很大

有的搜索引擎会把页面放进渲染队列,用无头浏览器跑一遍再抽取链接,但这个过程有延迟,也受资源预算限制;另一些搜索蜘蛛对 JS 的支持相对有限,动态插入的链接往往不会进入下一步抓取。

所以要分清两件事:链接能被浏览器看到,和链接能被搜索蜘蛛当成待抓取 URL 排进队列,不是一回事。前者靠渲染,后者要靠解析加渲染都走通。

几种常见写法,谁更容易被发现

直接写在 HTML 里的 a 标签

最稳的一类。只要 HTML 源码里存在 href,搜索蜘蛛在解析 HTML 阶段就能拿到,不需要等渲染。这也是判断问题出在哪一层时,最方便的对照基准。

放在 noscript 里

noscript 的内容在 HTML 源码中是真实存在的,通常能被解析到。但要注意别重复:如果页面同时用 JS 输出一份同样的链接,等于给同一批目标造了两套清单,出问题时不容易排查。另外,只在 noscript 里放链接、正常渲染时又被覆盖掉,效果也并不理想。

用 JS 遍历数组生成 a 标签

这类链接在源码里往往只是一个数组加一个循环。支持渲染的搜索蜘蛛在渲染完成后能拿到 DOM,但前提是脚本能下载、能执行,数据不依赖额外的异步请求。如果链接是靠 fetch 取回 JSON 再渲染,就要等接口返回,渲染超时或接口被 robots.txt 挡住,链接就丢了。

链接只写在 JS 字符串或 onclick 里

这种写法基本只能靠额外规则提取,属于最不保险的一类。如果这批 URL 是运营的重点资源,不值得为了省事放在这种位置。

想提高被发现的概率,可以从这几处下手

  1. 入口页的核心链接用服务端渲染或静态 HTML 输出,JS 只负责交互增强,不负责生成主体链接。
  2. 关键目标 URL 在页面上至少出现一次可点击的 a 标签,而不是只存在于事件处理里。
  3. 异步数据源不要放在被 robots.txt 拦住的路径下,否则渲染阶段取不到数据。
  4. 控制单页链接总量,不要把几万条 URL 全塞进一个依赖 JS 的列表里。
  5. 用日志验证效果,而不是凭感觉判断。看搜索蜘蛛有没有真的抓到新加的 URL。

怎么判断是渲染问题,还是别的环节

服务端至少记录两件事:入口页本身被抓取的请求,以及目标 URL 被抓取的请求。如果入口页被抓了、目标 URL 却从没出现过,再回头查看入口页的 HTML 源码里到底有没有那批链接。源码里没有、只有渲染后才有,问题基本就落在渲染这一层。

还有一种情况值得留意:源码里有链接,日志里也能看到蜘蛛抓了入口页,但抓取量远小于链接数。这通常是抓取配额在起作用,而不是链接没被发现,两者的处理方式完全不同。

渲染不是万能的。入口页做成“源码可见 + 浏览器可点”是最省事的状态,剩下的不确定性最终都会转成抓取延迟和 URL 漏抓。

最后提醒一点:入口页只负责发现 URL,不负责收录结果。即使链接被顺利发现,目标页能不能进索引,还要看内容质量、重复度、站点整体情况这些因素。把入口页结构做干净,能减少一类问题,但别指望它解决全部。