蜘蛛池知识

蜘蛛池入口页的 JavaScript 渲染:哪些内容必须写在初始 HTML 里

蜘蛛对 JS 的执行能力并不统一,入口页如果只靠客户端渲染,蜘蛛可能只看到空框架。本文讨论哪些链接、标题和声明必须放在初始 HTML,预渲染与动态渲染怎么选,以及常见误区和检查顺序。

蜘蛛池知识

蜘蛛池入口页的 JavaScript 渲染:哪些内容必须写在初始 HTML 里

蜘蛛对 JavaScript 的处理不是统一的

不同搜索引擎的蜘蛛对 JS 的执行能力差别很大。有的蜘蛛只抓取初始 HTML,不执行脚本;有的虽然能渲染,但会排入单独的渲染队列,时间上滞后很多。这就意味着,如果你的入口页把关键链接和内容都交给 JS 生成,蜘蛛可能只看到一个空框架。

所以讨论入口页的 JS 渲染,核心问题不是“能不能用 JS”,而是“哪些信息必须让蜘蛛在第一次抓取时就拿到”。

蜘蛛渲染和普通抓取不是一回事

即使蜘蛛具备渲染能力,很多搜索引擎也会把渲染放在独立的队列里。初始抓取和渲染之间可能间隔一段时间,入口页数量一多,这个延迟会被放大。如果你的入口页主要作用是传递链接权重和引导 URL 发现,等待渲染队列显然不划算。

另外,渲染会消耗更多资源。搜索引擎不会对每个页面都投入同样的渲染预算,入口页越薄、越模板化,被跳过渲染的概率越高。

这些内容建议放在初始 HTML 里

  • 可抓取的链接:指向目标页的 a 标签最好直接出现在 HTML 中,而不是等 JS 插入。蜘蛛顺着链接发现新 URL,依赖的就是这些初始的 href。
  • 页面主题相关的主标题和正文摘要:至少让蜘蛛读到入口页在讲什么,有助于判断是否继续抓取。
  • canonical 和 meta robots:这些声明如果由 JS 后置写入,蜘蛛可能来不及看到,规范化和屏蔽指令就会失效。
  • 状态码和跳转:服务端能返回的,不要改用前端路由或 JS 跳转代替。HTTP 层面的信号更明确。

预渲染与动态渲染的取舍

如果入口页确实需要 JS 才能展示完整内容,可以考虑预渲染或动态渲染,但要注意成本和一致性。

预渲染

在构建或缓存阶段就把页面渲染成静态 HTML,蜘蛛和用户拿到的是同一份内容。这种方式稳定,但内容更新后需要重新生成,适合入口页结构相对固定的场景。

动态渲染

根据 User-Agent 判断是否返回渲染后的 HTML。实现时要小心:蜘蛛 UA 会变化,伪装 UA 的爬虫也不少。如果只对特定 UA 返回不同内容,容易造成内容不一致,也可能被判定为作弊。更稳妥的做法是服务端渲染或同构渲染,让所有访问者拿到基本一致的 HTML。

几个容易踩的坑

  • 把链接做成 onclick 事件,或者用 javascript:void(0) 这类空地址,蜘蛛拿不到真实目标。
  • 首屏内容由接口异步加载,初始 HTML 里只有 loading 提示。
  • 用前端路由处理分页,URL 变了但 HTML 不变,蜘蛛容易把不同页看成同一页。
  • 依赖 JS 写入 meta 标签,比如 noindex 或 canonical,实际抓取时可能根本没生效。

怎么确认蜘蛛看到了什么

最直接的办法是看服务端日志里的请求。如果蜘蛛只请求了 HTML,没有请求 JS 和接口,那它大概率没有执行渲染,或者渲染在另一个阶段进行。也可以对比“源代码”和“渲染后 DOM”的差异,差异越大,风险越高。

如果日志显示蜘蛛抓取了 JS 文件,但入口页的链接仍然没有出现在后续抓取中,需要检查链接是否在初始 HTML 里,以及是否被 JS 条件隐藏。

一个简单的检查顺序

  1. 查看页面源代码,而不是开发者工具里的渲染后 DOM。源代码里有没有链接、标题和正文?
  2. 禁用浏览器 JavaScript,看页面还剩多少可读内容。
  3. 用抓取工具模拟蜘蛛,只拿初始 HTML,确认关键元素是否出现。
  4. 检查 canonical、meta robots 和主要链接是否都在服务端输出。
  5. 如果必须用 JS,评估预渲染或 SSR 的成本,别只靠动态渲染兜底。
入口页的 JS 策略,本质上是在“开发方便”和“蜘蛛可读”之间做取舍。能服务端输出的,尽量别留给客户端。