name: spa-scrape version: 1.0.0 description: | 将 SPA(单页应用)网站完整扒下来,生成纯静态 HTML 文件。 适用于 Vue/React/Angular 等前端框架渲染的网站。 触发词:"扒站"、"扒下来"、"抓取这个网站"、"spa scrape"、"静态化这个网站"。 allowed-tools:
- Bash
- Read
- Write
- Edit
- Grep
- Glob
- Agent
- AskUserQuestion
- mcp__playwright__browser_navigate
- mcp__playwright__browser_snapshot
- mcp__playwright__browser_evaluate
- mcp__playwright__browser_click
- mcp__playwright__browser_network_requests
- mcp__playwright__browser_network_request
- mcp__playwright__browser_take_screenshot
- mcp__playwright__browser_wait_for
- mcp__playwright__browser_run_code_unsafe triggers:
- 扒站
- 扒下来
- 把网站扒下来
- 抓取这个网站
- spa scrape
- 静态化这个网站
- 整站下载
SPA 网站扒站工具
将动态渲染的 SPA 网站(Vue/React/Angular)转换为纯静态 HTML 文件,保留布局和样式。
完整工作流程
阶段 1:探索网站结构
-
打开目标网站
browser_navigate → 目标 URL browser_wait_for → 等待 3-5 秒让 SPA 渲染完成 -
获取路由表(关键步骤)
browser_evaluate → 执行 JS 获取 Vue Router / React Router 路由表- Vue:
document.querySelector('#app').__vue_app__._instance.appContext.config.globalProperties.$router.options.routes - React: 查 Network 面板或遍历 DOM 导航链接
- 通用:
browser_snapshot获取页面结构,提取所有导航链接
- Vue:
-
发现静态资源
browser_network_requests → static=true → 列出所有 JS/CSS/图片/字体记录带 hash 的文件名(如
index-Cwp7s7md.js、a1-BKC9nY_U.png) -
触发懒加载
逐一点击导航链接 → browser_click → browser_wait_for → browser_network_requests发现微前端子应用、路由懒加载 chunk
阶段 2:下载资源
-
创建本地目录结构
mkdir -p <output-dir>/{assets,子应用目录...} -
下载入口 HTML
curl -sL -o <output-dir>/index.html <网站URL> -
批量下载静态资源
# 下载 JS/CSS curl -sL -o <output-dir>/assets/xxx.js <网站URL>/assets/xxx.js # 下载图片(带 hash 的文件名) curl -sL -o <output-dir>/assets/a1-XXX.png <网站URL>/assets/a1-XXX.png # 下载字体 curl -sL -o <output-dir>/assets/iconfont-XXX.woff2 <网站URL>/assets/iconfont-XXX.woff2并行下载: 用多个 subagent 同时下载不同目录的资源
阶段 3:捕获页面快照
- 逐个页面捕获渲染后的 HTML
并行处理: 用 subagent 同时抓取多个页面browser_navigate → 页面路由 browser_wait_for → 3 秒等待渲染 browser_evaluate → document.documentElement.outerHTML → 保存为 .html
阶段 4:清洗 HTML
-
去掉不需要的内容
import re # 去掉所有 <script> 标签 html = re.sub(r'<script[^>]*>.*?</script>', '', html, flags=re.DOTALL) # 去掉外部 JS 引用(保留模板语法如 {{ }}) # 去掉 <link rel="modulepreload"> html = re.sub(r'<link[^>]*modulepreload[^>]*>', '', html) -
修复资源路径
# 添加 <base> 标签让图片等资源从远程加载 html = html.replace('<head>', '<head><base href="https://原网站域名/">') # 修复相对路径 html = re.sub(r'url\(\./iconfont-', 'url(assets/iconfont-', html) html = re.sub(r'url\(\./(?!assets/)', 'url(https://原网站域名/', html) # 修复 CSS 中的 CORS 字体 html = html.replace("url(./", "url(assets/") -
修复渲染问题
# SVG 转义 html = html.replace('=\\"', '="') # 注入缺失的 Header/公共组件样式 # (某些页面依赖公共组件 CSS,需要手动注入)
阶段 5:验证
-
本地预览
# 启动简单 HTTP 服务器 cd <output-dir> && python3 -m http.server 8899然后在浏览器中逐个打开页面,检查:
- 布局是否正常
- 图片是否加载
- 字体图标是否显示
- 浏览器 Console 是否有 404/CORS 错误
-
修复问题
- CORS 错误 → 检查
base标签和资源路径 - 图片 404 → 检查 hash 文件名是否正确
- 样式缺失 → 注入缺失的 CSS
- 布局错乱 → 检查 CSS 文件是否完整下载
- CORS 错误 → 检查
常见陷阱
| 问题 | 原因 | 解决 |
|------|------|------|
| 图片 hash 错误 | 不同构建版本的 hash 不同 | 从 Network 面板确认当前 hash |
| CORS 字体加载失败 | url() 路径不对 | 改为本地路径或完整 URL |
| Header/导航样式缺失 | 微前端公共组件 CSS 未注入 | 手动注入 common-components CSS |
| SVG 图标显示异常 | Vue 渲染的 =\" 转义 | replace('=\\"', '="') |
| 页面跳转到登录 | Keycloak/OAuth 认证拦截 | 单独下载登录页,或跳过需要认证的路由 |
| 滚动触发路由切换 | SPA 的 scroll-to-anchor | 小心使用 browser_evaluate,避免触发滚动 |
输出物
<output-dir>/
├── index.html # 主入口
├── standalone-homepage.html # 首页完整快照(可直接浏览器打开)
├── all-styles.css # 所有 CSS 合并文件
├── screenshot-fullpage.png # 首页截图
├── <page1>.html # 各页面快照
├── <page2>.html
├── ...
├── assets/ # 静态资源
│ ├── *.js
│ ├── *.css
│ ├── *.png / *.jpg
│ ├── *.woff2 / *.ttf
│ └── *.mp4
└── <子应用>/ # 微前端子应用资源
└── ...
使用示例
用户: 把 https://example.com/#/ 这个网站扒下来
用户: spa-scrape https://example.com
用户: 静态化这个 Vue 网站
Next.js App Router Expert
Development
A skill that turns Claude into a Next.js App Router expert.
README Generator
Development
Creates professional and comprehensive README.md files for your projects.
API Documentation Writer
Development
Generates comprehensive API documentation in OpenAPI/Swagger format.