搜索抓取

蜘蛛看到的是源码还是渲染后的页面:JS 站点的抓取链路与常见断点

蜘蛛处理一个 JS 页面时,通常先拉取原始 HTML,再把依赖脚本的 URL 排进渲染队列。本文拆解这两次机会各自能拿到什么、在哪些环节容易断掉,以及如何用 URL 检查工具、服务器日志和禁用 JS 的对照来确认蜘蛛实际看到的内容。

搜索抓取

蜘蛛看到的是源码还是渲染后的页面:JS 站点的抓取链路与常见断点

越来越多站点把列表、详情甚至整站导航交给 JavaScript 渲染。结果是在浏览器里一切正常,在蜘蛛那边却只拿到一个空壳 HTML。要排查这类问题,先得理解一件事:搜索蜘蛛处理一个 URL,往往不是一次抓取,而是两次。

第一次:拉取原始 HTML

蜘蛛首先请求服务器返回的源码,也就是未执行脚本的那份 HTML。这个阶段它能读到服务端输出的标题、正文、链接、结构化数据和 meta 标签。如果链接在源码里就已经存在,蜘蛛可以直接顺着走;如果链接是脚本执行后才插入 DOM 的,第一次抓取时它看不到。

一个实用的判断标准是:关掉浏览器 JS,页面还剩多少可读内容和可点链接。剩下的那部分,就是蜘蛛在第一时间能拿到的东西。

第二次:进入渲染队列

对于确认依赖脚本的页面,搜索引擎会安排一次渲染,用无头浏览器执行 JS 并读取渲染后的 DOM。这一步有几个特点:

  • 排队:渲染资源有限,通常是先发现、后渲染,存在延迟,也不是每个 URL 都能排上。
  • 超时:脚本执行、接口请求、图片与字体加载都有时间上限,超出的部分拿不到。
  • 不交互:不会点按钮、不会滚动到底、不会关闭弹窗、不会填表单。

换句话说,渲染阶段能救回一部分内容,但它不是保险,更像一次补考。

常见的抓取断点

1. 内容完全靠接口异步拉取

页面源码里只有容器和脚本,数据要等接口返回才出现。如果接口响应慢、需要特定请求头,或者对爬虫 UA 返回不同结果,渲染时同样可能拿不到东西。

2. 链接依赖点击或滚动

加载更多按钮、无限滚动、Tab 切换,都会让后续内容在渲染阶段也不出现在首屏。分页入口如果只是脚本事件而不是真实链接,抓取路径就断在这里。

3. 懒加载与占位内容

图片、评论区等资源进入视口才加载,渲染器不一定滚动,于是这部分可能长期不参与抓取。

4. 登录、验证码与地区限制

被拦住的页面在源码阶段就可能拿到 403 或跳到登录页,后续渲染更无从谈起。

5. 渲染脚本本身报错

JS 抛错、依赖的外链资源被墙、跨域请求被拒,都会让 DOM 停在半成品状态。

怎么确认蜘蛛到底看到了什么

  1. 用搜索引擎提供的 URL 检查工具,对比原始 HTML 与渲染后 HTML 两种视图。
  2. 在服务器日志里看该 URL 的抓取次数与状态码,渲染抓取有时表现为同一路径的再次访问或来自不同 UA 的请求。
  3. 用浏览器禁用 JS 打开页面,记录缺失的正文和链接。
  4. 检查接口是否对爬虫请求做了差异化返回,这一点往往最容易被忽略。

让链路更稳的一些做法

  • 关键内容与主导航尽量服务端渲染,或做同构输出,让源码里就有可读信息。
  • 分页、详情入口用真实的链接标签承载,而不是纯点击事件。
  • canonical、robots meta 这类指令放在服务端输出,不要靠脚本动态写入。
  • 接口保持稳定响应,避免对正常抓取做额外拦截。
  • 懒加载尽量留一条不依赖交互的加载路径,或让首屏内容直接输出。

还要提醒一点:渲染能力是逐步获得的。新站、内容更新频率低的站点,排到渲染队列的机会相对更少。把关键内容放进源码,永远比等渲染更省事,也更可控。

能被抓取的内容,往往先能被“不执行脚本”地读到。