view-source 与右键另存为拿到的都是服务端返回的原始 HTML,JavaScript 生成的节点不在其中。要保留渲染后的结果,得从 DOM 层取快照,按需求强度选方案。

四种方案的差别
| 方案 | 拿到什么 | 适用场合 | 成本 |
|---|---|---|---|
| 浏览器另存为 | 原始 HTML 加资源 | 静态页、少量页面 | 低 |
| 开发者工具复制 outerHTML | 当前 DOM 快照 | 单次取证、调试 | 低 |
| curl 或 wget | 服务端响应原文 | 接口与静态页抓取 | 中 |
| 无头浏览器 | 渲染后 DOM 加可选资源 | 批量、离线保存 | 高 |
单次取样:开发者工具
Elements 面板选中 html 节点,右键 Copy → Copy outerHTML,得到的是此刻完整的 DOM 字符串。SPA 页面要先操作到目标状态(展开、滚动加载完成)再复制,否则拿到的是半成品。
批量保存:无头浏览器
const html = await page.goto(url, { waitUntil: 'networkidle0' });
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await page.waitForTimeout(1000);
const dom = await page.content();
waitUntil: 'networkidle0'等网络空闲,避免拿到未完成的渲染结果;- 先滚动到底再等待,覆盖懒加载内容;
page.content()返回序列化后的 DOM,写文件即可得到快照。
需要完整离线时
只保存 DOM 字符串并不能离线打开,图片、样式、字体仍指向远端。要可离线浏览,需要同时抓取资源并改写引用路径:
await page.setRequestInterception(true);
// 拦截请求 → 落盘本地 → 改写 HTML 中的引用地址
资源抓取要注意跨域名限制、query 参数去重与文件名冲突,这三项是离线包最常见的失败点。
取舍顺序
- 只要一份渲染后的结构 → 开发者工具复制;
- 要批量重复执行 → 无头浏览器取 page.content();
- 要可离线打开 → 在上一步基础上补资源抓取与路径改写;
- 页面本身由服务端渲染 → curl 或 wget 已足够,无需引入浏览器。
