搜索抓取

JS 渲染与蜘蛛抓取:蜘蛛第一次拿到的是没跑脚本的页面

页面在浏览器里看起来很完整,蜘蛛第一次请求却可能只拿到一副骨架。抓取和渲染是两个独立步骤,渲染要额外消耗抓取资源,还可能延迟甚至走不完。本文说明原始 HTML 与渲染结果的落差从哪来,哪些写法会让内链和正文在第一次抓取时消失,以及怎样用服务端输出、Sitemap 兜底和资源放行把两条发现路径都铺稳。

搜索抓取

JS 渲染与蜘蛛抓取:蜘蛛第一次拿到的是没跑脚本的页面

很多站点把内容交给前端框架渲染,页面在浏览器里看着完整,但蜘蛛第一次请求拿到的那份 HTML,往往只有骨架。把“抓取”和“渲染”当成两件独立的事来看,比纠结某个标签更能解释收录慢的原因。

抓取和渲染不是同一个动作

蜘蛛访问一个 URL 时,第一步永远是发 HTTP 请求,拿服务器返回的原始内容。这一步只看响应,不执行页面里的脚本。真正需要 JavaScript 才会出现的内容,会被排进渲染队列,由渲染环节稍后执行脚本、拿到最终 DOM。这个过程可能延迟几分钟到几天,也可能因为资源抓取失败而根本走不完。

也就是说,同一个 URL 在蜘蛛眼里可能有两个版本:第一次看到的原始 HTML,和渲染之后的完整页面。如果关键信息只存在于第二个版本,等于把发现时机往后推,还可能推丢。

渲染要额外花掉抓取成本

渲染不是免费的。要跑脚本,蜘蛛还得去抓 HTML 里引用的 JS、CSS,甚至接口返回,这些都会算进站点的抓取消耗,而渲染队列通常比普通抓取队列更拥挤。

  • 被 robots.txt 挡住的 JS、CSS,会让渲染结果残缺;
  • 需要登录、点击、滚动才出现的内容,多数情况下不会被自动补齐;
  • 脚本里拼接出来的链接,在原始 HTML 里并不存在,相当于少了一条发现路径。

几个容易踩的位置

  1. 把内链写进脚本。列表页、分页、相关推荐如果用 JS 插入链接,蜘蛛第一次抓取时看不到这些 URL。改成服务端输出,或至少在 HTML 里保留可点击的链接,能省掉一轮渲染等待。
  2. 关键正文懒加载。首屏之外的内容等到滚动才请求,渲染环节不一定模拟这个动作。
  3. 接口数据当成正文。内容全靠异步请求拉取,接口又没有别的入口被发现,抓取和索引都容易悬空。
  4. 分页只留一个“加载更多”。没有真实可抓的下一页 URL,深分页的内容基本只能靠 Sitemap 兜底。

让两条发现路径都成立

比较稳的思路是双层保障:

  • HTML 层:标题、正文主体、主要导航和内链尽量由服务端输出,保证不执行脚本也能看出一条完整的抓取路径。
  • URL 层:重要页面整理进 Sitemap,用 lastmod 标出真实更新时间,让蜘蛛不必依赖脚本就能发现新 URL。
  • 资源层:确认 JS、CSS、接口没有被 robots.txt 拦住,返回码稳定,别让渲染抓到一半断掉。

怎么验证这道落差

最简单的检查是关掉浏览器的 JavaScript 再刷新页面,看看还剩多少内容、还剩多少链接,这一步能直观暴露蜘蛛第一次看到什么。再对照服务器日志里 JS、CSS、接口的请求比例,判断渲染是否真的发生过。搜索平台的抓取测试工具也能用来对比原始 HTML 与渲染结果。

不必追求整站改造

不用为了这件事把整站都改成服务端渲染,也没必要把所有内容硬塞进 HTML。优先把离正文最近的路径做扎实:入口页、列表页、分页、详情页之间的内链,以及正文本身。这些位置少一层脚本依赖,抓取路径就少一个断点。

把内容藏在脚本后面,等于让蜘蛛排队等你;把发现路径放在 HTML 里,蜘蛛才知道下一步该去哪。