一键保存网页 + 提取可交互元素 | 侧边栏UI,更大空间,更好体验
将网页保存为完整的HTML文件,所有资源内联(图片、CSS、图标)
特性:
- 自动处理懒加载图片、Shadow DOM、iframe、Canvas
- 移除追踪代码(Google Analytics、百度统计等)
- CORS代理支持跨域资源
一键提取页面所有可交互元素,在侧边栏中分类展示,支持元素定位和选择器生成
提取内容:
- 元素类型:按钮、链接、表单、输入框、下拉框、文本域、自定义组件
- 完整属性:id、class、name、type、placeholder、验证规则等
- 自定义属性:data-*、aria-label、onclick 事件等
智能定位:
- 多重选择器:为每个元素生成 XPath、CSS(ID/Class/Attribute/nth-child)等多种选择器
- 元素高亮:点击侧边栏中的元素,页面自动滚动并高亮显示对应元素(持续5秒)
- 可靠性标识:选择器按可靠性分级(🟢 高可靠 🟡 中等 🔴 低可靠)
- 一键复制:所有选择器支持复制到剪贴板,方便测试和自动化
- React 18.2.0 - UI框架(侧边栏界面)
- TypeScript 5.9 - 类型安全的开发语言
- Material-UI v7.3.4 - 现代化组件库
- Emotion - CSS-in-JS样式解决方案
- Webpack 5 - 模块打包器
- ts-loader - TypeScript加载器
- html-webpack-plugin - HTML文件生成
- copy-webpack-plugin - 资源文件复制
- Axios - HTTP客户端(预留)
- Fetch API - 资源获取
- Chrome Extension API - 扩展通信
- Node.js 16+ 和 npm
- Chrome浏览器
cd d:\backend_learningnpm installnpm run dev文件修改后自动重新构建,但需要手动刷新Chrome扩展
npm run build生成优化后的生产版本到 dist/ 目录
npm run type-check运行TypeScript类型检查而不构建
- 打开Chrome浏览器
- 在地址栏输入:
chrome://extensions/ - 打开右上角的 "开发者模式" 开关
- 点击 "加载已解压的扩展程序"
- 选择项目中的
dist文件夹(不是项目根目录!) - 完成!扩展图标会出现在工具栏
开发流程:
- 运行
npm run dev启动监听模式 - 修改
src/下的源代码 - Webpack自动重新构建到
dist/ - 在Chrome扩展页面点击扩展的"刷新"按钮
- 重新打开侧边栏测试
调试工具:
- 侧边栏调试:右键侧边栏 → 检查
- 后台脚本调试:扩展详情页 → Service Worker → 检查
- 内容脚本调试:页面右键 → 检查 → Console(查看content.js日志)
点击扩展图标 → 自动打开侧边栏(提供更大操作空间)
侧边栏中点击 "保存当前页面" → 自动下载完整HTML
侧边栏中点击 "提取可交互元素" → 在侧边栏查看分类展示的元素
交互功能:
- 📊 分类展示 - 按钮、链接、表单等分标签页显示,一目了然
- 🎯 元素定位 - 点击任意元素,页面自动滚动到该元素并高亮显示
- 📋 选择器列表 - 展开元素查看所有可用选择器(XPath、CSS等)
- 📝 复制选择器 - 一键复制选择器,方便用于自动化测试或爬虫开发
- 🟢 可靠性指示 - 不同颜色标识选择器的稳定性和唯一性
使用示例:
1. 打开任意网页(如 https://csdiy.wiki/)
2. 点击扩展图标打开侧边栏
3. 点击"提取可交互元素"按钮
4. 查看分类统计和元素列表
5. 点击表格中任一行 → 页面滚动 + 元素高亮
6. 点击展开图标 ▼ → 查看该元素的所有选择器
7. 点击复制图标 📋 → 选择器已复制到剪贴板
d:\backend_learning\
├── 📁 src/ # 源代码目录
│ ├── 📁 sidepanel/ # React侧边栏应用
│ │ ├── App.tsx # 主React组件
│ │ ├── index.tsx # React入口
│ │ ├── index.html # HTML模板
│ │ ├── 📁 components/ # React组件
│ │ │ ├── SavePageButton.tsx # 保存页面按钮
│ │ │ ├── ExtractButton.tsx # 提取元素按钮
│ │ │ ├── ElementsDisplay.tsx # 元素展示组件(分类表格+选择器)
│ │ │ ├── ProgressBar.tsx # 进度条
│ │ │ └── StatusMessage.tsx # 状态消息
│ │ ├── 📁 services/ # 业务逻辑
│ │ │ ├── pageExtractor.ts # 页面保存服务
│ │ │ └── elementExtractor.ts # 元素提取服务(已废弃,逻辑在content.ts)
│ │ └── 📁 types/ # TypeScript类型定义
│ │ └── index.ts
│ ├── 📁 background/ # 后台服务
│ │ └── background.ts
│ ├── 📁 content/ # 内容脚本
│ │ └── content.ts
│ └── 📁 public/ # 静态资源
│ ├── manifest.json # 扩展清单
│ └── icons/
├── 📁 dist/ # Webpack构建输出(加载此目录)
│ ├── sidepanel.html
│ ├── sidepanel.js
│ ├── background.js
│ ├── content.js
│ ├── manifest.json
│ └── *.png # 图标文件
├── 📄 package.json # 依赖配置
├── 📄 tsconfig.json # TypeScript配置
├── 📄 webpack.config.js # Webpack配置
└── 📄 README.md # 本文件
用户点击图标 → background.ts 打开侧边栏
↓
React App (sidepanel)
├── 💾 保存页面
│ └── 注入 pageExtractor → 内联资源 → 下载HTML
└── 📋 提取元素
└── content script 提取元素 + 生成选择器
↓
ElementsDisplay 组件展示
↓
点击元素 → background → content script → 高亮显示
- 使用MUI组件构建现代化UI
- ThemeProvider提供紫色渐变主题
- TypeScript类型安全保证
- 多入口点配置(sidepanel、background、content)
- ts-loader编译TypeScript
- 生产环境代码压缩优化
- Service Worker后台脚本
- Side Panel API侧边栏
- Scripting API动态注入
- 类型安全的消息通信
- 优先尝试content script通信
- 失败则使用executeScript动态注入
- 函数序列化注入(不能使用外部依赖)
- Fetch + FileReader转Base64
- CORS代理fallback(通过background)
- 超时控制(5秒)
- 懒加载属性识别(10+种)
- XPath生成:完整路径 + 优化短路径(基于ID)
- CSS选择器:ID、Class、Attribute、nth-child、组合选择器
- 临时标记:
data-extract-id属性确保精确定位 - 7级回退策略:从最可靠到最不可靠依次尝试
1️⃣ data-extract-id(临时标记)→ 最可靠 🟢 2️⃣ CSS by ID(#id)→ 高可靠 🟢 3️⃣ XPath(short/full)→ 中等可靠 🟡 4️⃣ CSS Combined(标签+类+属性)→ 中等可靠 🟡 5️⃣ CSS by Class(.class)→ 中等可靠 🟡 6️⃣ CSS by Attribute([name=...])→ 中等可靠 🟡 7️⃣ CSS nth-child(:nth-child(n))→ 低可靠 🔴 - 动态高亮:CSS动画 + 自动清理(5秒超时)
| 层级 | 之前(Vanilla JS) | 现在(React + TS) |
|---|---|---|
| UI框架 | 原生HTML/CSS | React 18 + MUI v7 |
| 语言 | JavaScript | TypeScript 5.9 |
| 样式 | 内联CSS | Emotion CSS-in-JS |
| 构建 | 无 | Webpack 5 |
| 类型检查 | ❌ | ✅ 完整类型定义 |
| 组件化 | ❌ | ✅ React组件 |
| 开发体验 | 手动刷新 | 热重载(需刷新扩展) |
| 代码组织 | 单文件 | 模块化目录结构 |
| 问题 | 原因 | 解决 |
|---|---|---|
| 扩展无法加载 | 选错了目录 | 加载 dist/ 文件夹,不是项目根目录 |
| 修改代码不生效 | 未重新构建 | 运行 npm run dev 或 npm run build |
| 构建失败 | 依赖未安装 | 运行 npm install |
| 类型错误 | TypeScript检查 | 运行 npm run type-check 查看详情 |
| 提取失败 | 特殊页面或权限 | 在普通网页使用,避免 chrome:// |
| 高亮不生效 | Content script未加载 | 刷新页面后重试(扩展更新后需要) |
| 选择器不显示 | 扩展版本不匹配 | 重新构建 npm run build 并刷新扩展 |
| 资源缺失 | CORS跨域限制 | 正常现象,已自动跳过(5秒超时) |
| Bundle过大警告 | React+MUI体积 | 可忽略,Chrome扩展无严格限制 |
-
添加新的UI组件:
- 在
src/sidepanel/components/创建新的.tsx文件 - 使用MUI组件和TypeScript类型
- 在
App.tsx中引入并使用
- 在
-
添加新的业务逻辑:
- 在
src/sidepanel/services/创建新的服务 - 定义类型在
src/sidepanel/types/index.ts - 在组件中调用服务
- 在
-
修改样式:
- 使用MUI的
sxprop或styled组件 - 遵循Material Design设计规范
- 保持紫色渐变主题一致性
- 使用MUI的
所有主要数据结构都在 src/sidepanel/types/index.ts 中定义:
SaveOptions- 保存选项ElementData- 提取的元素数据ElementSelectors- 元素选择器集合(XPath、CSS等)ChromeMessage- 消息类型(类型安全通信)- 各种元素类型:
ButtonElement、LinkElement、FormElement等
- React DevTools:安装React DevTools扩展查看组件状态
- TypeScript错误:查看终端输出的详细错误信息
- Chrome API:在console中直接调用
chrome.*API测试 - 网络请求:在Network面板查看资源加载情况
| 版本 | 日期 | 主要更新 |
|---|---|---|
| v2.1.0 | 2025-11-05 | 🎯 元素定位功能: ✨ 智能选择器生成(XPath + 多种CSS选择器) 🎨 点击元素自动滚动并高亮 📋 可展开查看所有选择器 📝 一键复制选择器到剪贴板 🟢 选择器可靠性标识 🔧 7级回退定位策略 |
| v2.0.0 | 2025-11-05 | 🎉 重大重构:迁移到 React + TypeScript + MUI ✨ 现代化技术栈 🔧 Webpack构建系统 📦 完整类型定义 🎨 Material-UI组件库 |
| v1.2.0 | 2025-11-05 | 🎨 侧边栏UI、更大操作空间、更好体验 |
| v1.1.0 | 2025-11-05 | ✨ 提取元素功能(已重构) |
| v1.0.0 | 2025-11-04 | 🚀 基础保存功能、资源内联、追踪器移除 |
- Fork项目
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启Pull Request
MIT License - 详见LICENSE文件
开发环境: Node.js 16+ | npm 7+ | Chrome 88+
Build Status: ✅ 构建成功 | 📦 生产就绪