搜索抓取

JS 渲染队列与蜘蛛抓取:脚本生成的链接什么时候才进入路径

页面上的链接如果由 JavaScript 在加载后生成,搜索蜘蛛首轮抓取拿到的 HTML 里就没有这些入口,只能等渲染队列的后续访问。本文说明首轮抓取与渲染两轮之间的时间差,哪些链接适合由服务端直接输出,以及怎样用禁用 JS 对比、日志抽查来确认关键 URL 是否真的进入了抓取路径。

搜索抓取

JS 渲染队列与蜘蛛抓取:脚本生成的链接什么时候才进入路径

很多站点的链接并不是写在 HTML 里,而是页面加载后由 JavaScript 拼出来的。对用户来说,点开就看到了;对搜索蜘蛛来说,这件事要分两步看。第一轮请求拿到的往往只是一段初始 HTML,脚本还没执行,链接自然也不存在。这就是“页面上明明有入口,蜘蛛却像没看见”的常见原因。

第一轮抓取,蜘蛛先拿到什么

蜘蛛发出的第一次请求和普通的抓取请求很接近:它拿到服务器返回的 HTML,解析里面的 a 标签、link 标签、图片地址等。如果这份 HTML 里没有目标 URL,这一轮就发现不了它,后面的路径也就无从谈起。

蜘蛛确实具备渲染能力,但渲染成本更高,通常不是首轮就做,而是把需要渲染的 URL 放进队列,稍后再用另一轮请求以渲染方式访问。也就是说,脚本生成的链接不是不能被抓,而是要等,而且不保证等到。

渲染队列带来的时间差

  • 链接出现在渲染之后,不等于出现在首轮抓取路径里;
  • 排队意味着延迟,越靠后、越不被重视的页面等得越久;
  • 数据依赖接口返回,接口拒绝了蜘蛛的请求,链接就直接消失;
  • 需要滚动、点击、登录才出现的链接,大概率永远进不了队列。

所以真正的问题不是“渲染会不会被处理”,而是“你愿不愿意把关键入口押在第二轮上”。更新频繁的列表页、商品页、文章页,等一轮队列的代价很明显;而登录后、后台类页面本来也不需要被抓,延迟甚至抓不到都无所谓。

把结构性链接放回初始 HTML

最省事的做法是先分清楚哪些链接属于结构性入口——主导航、分类页、分页、上一页下一页、面包屑、相关推荐。这些应该由服务端直接输出成可点击的 a 标签,而不是留给脚本补上。

  1. 列表页与详情页的静态部分优先做服务端渲染或预渲染;
  2. 分页使用真实 URL,例如 ?page=2 或 /list/2,不要只在脚本里追加数据;
  3. 筛选、排序这类交互,至少保证有一个可抓取的默认版本;
  4. 跳转写成带 href 的链接,避免用 onclick 或 div 模拟。
判断标准很简单:把浏览器 JS 关掉再刷新页面,如果关键入口还在,蜘蛛第一轮大概率也能看到。

几项可以自己做的自查

  • 用抓取工具分别查看禁用 JS 与启用 JS 两种状态下的链接列表,对比差异;
  • 在服务器日志里观察同一个 URL 是否被多次访问,以及两次访问之间隔了多久;
  • 抽查 URL 检查类工具返回的原始 HTML 与渲染后 HTML,确认目标链接出现在哪一份里。

容易被忽略的连带影响

渲染后的页面还可能改变地址本身:脚本里带 hash、附加追踪参数、动态拼接路径,都会让同一份内容变成多个 URL,抓取路径随之走偏。渲染前和渲染后如果 canonical、标题、内链不一致,蜘蛛两次看到的就不是同一页,之前建立起来的路径判断也会被推翻。

结论并不复杂:渲染可以当作补充,但不适合当成发现 URL 的主通道。把结构性链接放回初始 HTML 和 Sitemap,让首轮抓取就能顺着走;剩下的交互再交给脚本处理,这样路径才稳定。