You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何获取单页应用(SPA)中动态渲染完成的HTML内容

如何获取SPA(如LeetCode)完全渲染后的HTML

你说得太对了——fetch本身确实只能拿到服务器返回的初始静态HTML,完全处理不了浏览器端JavaScript动态渲染的内容,而LeetCode刚好是用React构建的单页应用(SPA),大部分核心内容都是客户端JS跑起来之后才生成的。要拿到#app里填充好的完整内容,你有两个主要方向可选:

1. 用无头浏览器模拟完整渲染流程(最直接)

既然fetch没有浏览器的JS执行能力,那我们就直接用工具模拟一个真实浏览器环境,让页面完整加载、执行所有JS后再抓取HTML。最常用的两个工具是:

Puppeteer(Chrome官方无头浏览器)

它能完全模拟Chrome的行为,等待页面渲染完成后再获取完整DOM。示例代码如下:

const puppeteer = require('puppeteer');

async function fetchRenderedLeetCodeHTML() {
  // 启动无头浏览器
  const browser = await puppeteer.launch({ headless: 'new' });
  const page = await browser.newPage();
  
  // 加载页面,等待网络空闲(确保动态内容渲染完成)
  await page.goto('https://leetcode.com', { waitUntil: 'networkidle2' });
  
  // 获取完全渲染后的完整HTML
  const fullRenderedHTML = await page.content();
  
  await browser.close();
  return fullRenderedHTML;
}

// 调用函数并处理结果
fetchRenderedLeetCodeHTML().then(html => {
  console.log(html); // 这里的HTML会包含#app里的所有动态内容
});

注:waitUntil: 'networkidle2'表示等待页面加载后,只有2个以内的网络请求活跃时再继续,能有效确保大部分动态内容都渲染完毕。

Playwright(多浏览器支持)

和Puppeteer类似,但支持Chrome、Firefox、Safari等多种浏览器,API设计更现代化,用法也大同小异,适合需要跨浏览器兼容的场景。

2. 直接调用LeetCode的API(更高效)

如果你只是想爬取具体数据(比如题目列表、用户提交记录等),其实完全没必要渲染整个页面——LeetCode的所有动态内容都是通过后端API获取的。你可以:

  • 打开浏览器的开发者工具(F12),切换到Network面板
  • 刷新页面或操作你要爬取的内容,观察XHR/fetch请求
  • 找到对应的API接口(比如题目列表接口、题目详情接口),直接用fetch或其他HTTP工具调用这些接口,拿到结构化的JSON数据

这种方式不仅效率更高,还能避免渲染页面带来的性能开销,也更不容易触发反爬机制。

再明确下为什么fetch不行

简单来说:

  • fetch只是发送HTTP请求,拿到的是服务器返回的初始静态HTML(也就是你在浏览器里右键“查看页面源代码”看到的内容),这时候#app确实是空的,因为React还没在客户端执行渲染。
  • 浏览器的“检查元素”看到的是DOM树,是JS执行后动态生成的内容,fetch没有浏览器的渲染引擎和JS执行环境,根本触达不了这个阶段。

内容的提问来源于stack exchange,提问作者Louie Holbrook

火山引擎 最新活动