# legado-source-generator **Repository Path**: wzal/legado-source-generator ## Basic Information - **Project Name**: legado-source-generator - **Description**: 一个 Chrome 扩展,通过可视化点选页面元素来生成阅读 APP 的书源规则。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-08-18 - **Last Updated**: 2026-08-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Legado 书源生成器 > ⚠️ **风险提示**:本项目完全由 AI 辅助生成(vibe coding),代码可能存在缺陷、安全漏洞或有害内容。作者不对使用本项目产生的任何后果负责。使用者在安装或使用前,请务必自行审查代码,确保安全。 一个 Chrome 扩展,通过可视化点选页面元素来生成[阅读](https://github.com/gedoor/legado) APP 的书源规则。 ## 交流群 1101980180 ## 想用ai自动化编写调试书源? 试试[legado-book-source-skill](https://github.com/z1131392774/legado-book-source-skill) ## 演示视频 [![6分44秒生成完整书源并调试成功](https://socialify.git.ci/z1131392774/legado-source-generator/image?description=1&font=Inter&language=1&name=1&owner=1&theme=Auto)](https://www.bilibili.com/video/BV1ipDdBkEjA/) > 👆 点击观看完整演示视频 ## 功能特性 - **可视化元素选择**:点击选择页面上任意元素 - **智能选择器生成**:自动生成稳定的 CSS 选择器 - **分步工作流**:支持发现页、搜索页、详情页、目录页、正文页五种规则类型 - **列表交集算法**:选择两个同列表元素,自动提取公共 class 生成可复用选择器 - **错误检测**:自动检测 Shadow DOM、iframe、动态 class 等潜在问题 - **键盘导航**:支持 ↑↓←→ 键在 DOM 树中精确导航 - **导出 JSON**:一键生成可直接导入阅读 APP 的书源规则 - **自动填充**:一键从当前页面自动填充书源名称和 URL - **检查更新**:自动对比 GitHub 最新版本 - **状态持久化**:所有填写内容自动保存,关闭浏览器后不丢失 - **发现页 URL 编辑**:支持可视化卡片编辑、页面收集、批量 URL 替换、样式模板管理 - **搜索 URL 编辑**:支持自动捕获搜索请求 URL,自动生成带占位符的搜索 URL ## 安装 ### Chrome / Edge 1. 打开浏览器,访问 `chrome://extensions/` 2. 开启右上角的"开发者模式" 3. 点击"加载已解压的扩展程序",选择 `src` 目录 4. 建议固定扩展图标方便使用 ### Firefox > ⚠️ **注意**:本扩展主要基于 Chrome (MV3) 开发和测试,Firefox 版本(MV2)为适配移植版本,可能存在未知 bug。如遇问题,请优先使用 Chrome / Edge 版本。 #### 方式一:从扩展商店安装(推荐) 1. 打开 Firefox,访问 [Firefox 扩展商店](https://addons.mozilla.org/) 2. 搜索 **Legado Source Generator** 3. 点击"添加到 Firefox"完成安装 #### 方式二:手动加载(开发/测试) 1. 打开浏览器,访问 `about:debugging#/runtime/this-firefox` 2. 点击"临时载入附加组件" 3. 选择 `src-firefox/manifest.json` 文件 4. 点击工具栏扩展图标即可打开侧边栏 ## 使用方法 ### 规则页(发现页 / 搜索页 / 详情页 / 目录页 / 正文页) 1. 点击扩展图标打开侧边栏 2. 填写书源名称和基础 URL 3. 选择规则类型(发现页 / 搜索页 / 详情页 / 目录页 / 正文页) 4. 点击"选择元素"开始点选: - **列表字段**(书籍列表/章节列表):选择两个同列表元素,自动取交集 - **普通字段**:直接点击目标元素 5. 使用键盘快捷键精确调整: - `↑` 移动到父元素 - `↓` 移动到第一个子元素 - `←` 移动到上一个兄弟元素 - `→` 移动到下一个兄弟元素 - `Enter` 确认选择 - `Esc` 取消选择 6. 完成后点击"导出 JSON"获取书源规则 7. 导入到阅读 APP ### 捕获搜索 URL 如果当前页面有搜索功能,可以自动捕获搜索请求的 URL 格式。 1. 切换到"搜索URL"标签页 2. 点击 **🔍 捕获** 按钮 3. 页面提示"请点击网站的'搜索'按钮",此时**点击网站页面的搜索按钮**(无需手动输入) 4. 扩展会自动捕获请求,成功后表单自动填充: - **请求方法**:GET / POST - **charset**:自动检测(utf-8 / gbk / big5 等) - **请求体**:POST 时显示,搜索词已替换为 `{{key}}` - **搜索 URL**:自动生成 `{{key}}` 占位符 5. 如需分页,点击 **{{page}}** 按钮插入页码占位符 6. 表单内容实时同步到下方的搜索 URL 输入框 > **提示**: > - GET 请求输出格式:`https://example.com/search?key={{key}}&page={{page}}` > - POST 请求输出格式:`https://example.com/search,{"charset":"gbk","method":"POST","body":"kw={{key}}&page={{page}}"}` > - 扩展支持多种字符编码(UTF-8、GBK、BIG5 等),捕获时自动检测 > - 如未检测到搜索表单,表单各字段可手动填写 ### 发现页 URL 发现页 URL 用于配置阅读 APP 首页的分类导航入口,支持可视化编辑和页面收集两种模式。 #### 可视化编辑 1. 切换到"发现页"标签页 2. 点击"手动添加"逐条输入分类名称和 URL 3. 点击"插入分隔"添加分隔符 4. 卡片支持拖拽排序和拖拽调整宽度 5. 右侧属性面板可调整 Flexbox 布局属性(flexGrow、flexShrink、alignSelf、flexBasisPercent、wrapBefore) 6. 底部预览区实时显示生成的 JSON,支持"样式一"(每行 `title::url`)和"样式二"(JSON 数组)两种格式切换 #### 从页面收集 1. 在浏览器中打开目标网站(如小说网站的首页) 2. 在侧边栏发现页标签下点击"从页面收集元素" 3. 鼠标悬停在页面的分类/排行链接上,侧边栏预览区下方实时显示元素信息 4. 点击链接即可收集,已收集项会显示蓝色闪烁提示 5. 收集完成后按 `Enter` 完成收集,所有条目自动添加到列表 6. **重要**:生成的 URL 通常不带分页参数,需要手动在 URL 中添加 `{{page}}` 占位符,例如将 `https://example.com/category/1` 改为 `https://example.com/category/{{page}}`,否则翻页不会生效 #### 批量修改 URL 收集或手动添加完成后,通常需要批量修改 URL 以适配阅读 APP 的分页机制。扩展提供两种批量修改模式:**模板匹配**和**正则匹配**。 ##### 前置操作 1. 在发现页 URL 编辑器中,点击工具栏的 **"开启复选"** 勾选框 2. 勾选需要修改 URL 的卡片(或使用 **"全选"** / **"反选"** 快速选择) 3. 点击 **"批量改 URL"** 打开批量修改弹窗 ##### 模式一:模板匹配(推荐) 模板匹配模式通过分类占位符和翻页模板自动替换 URL,适用于网站 URL 有明确分类和分页规律的场景。 **字段说明:** | 字段 | 说明 | |------|------| | **分类匹配模板** | 以"第一页 URL"为基准,将分类部分替换为 `分类` 占位符,其余保持不变 | | **翻页模板** | 以"第二页(或分页页)URL"为基准,将分类部分替换为 `分类`,页码数字替换为 `页码` | | **第一页差异** | 当第一页 URL 与分页 URL 结构不同时,填写第一页多出来的那一段(含页码) | **规则 1:第一页与分页 URL 结构相同(仅页码数字不同)** 此时"第一页差异"留空。例如: - 第一页:`https://www.example.com/fantasy/1` - 第二页:`https://www.example.com/fantasy/2` 填写: - 分类匹配模板:`https://www.example.com/分类/1` - 翻页模板:`https://www.example.com/分类/页码` - 第一页差异:(留空) 处理后:`https://www.example.com/fantasy/<,页码>` → 实际效果为 `https://www.example.com/fantasy/{{page}}` **规则 2:第一页与分页 URL 结构不同** 当第一页没有页码变量时,"第一页差异"填写分页 URL 中多出来的那一段。例如: - 第一页:`https://www.example.com/fantasy/` - 第二页:`https://www.example.com/fantasy/index_2.html` 填写: - 分类匹配模板:`https://www.example.com/分类/` - 翻页模板:`https://www.example.com/分类/index_页码.html` - 第一页差异:`index_页码.html` 处理后:`https://www.example.com/fantasy/<,index_{{page}}.html>` **规则 3:分类和页码都在 URL 路径中** 例如: - 第一页:`https://www.example.com/tags-150-0.html`(150 是分类 ID,0 表示第一页) - 第二页:`https://www.example.com/tags-150-1.html` 填写: - 分类匹配模板:`https://www.example.com/tags-分类-0.html` - 翻页模板:`https://www.example.com/tags-分类-页码.html` - 第一页差异:(留空) 处理后:`https://www.example.com/tags-150/<,{{page}}.html>` ##### 模式二:正则匹配 正则匹配模式使用自定义正则表达式进行 URL 替换,适用于更灵活或更复杂的替换需求。 **字段说明:** | 字段 | 说明 | |------|------| | **正则表达式** | 匹配 URL 中需要替换的部分,如 `/sort/xuanhuan/` | | **替换为** | 替换后的内容,如 `/sort/分类/` | | **全局替换(g)** | 勾选后会替换所有匹配项(默认开启) | | **忽略大小写(i)** | 勾选后不区分大小写 | **示例:** 将多个分类 URL 中的具体分类名统一替换为 `分类` 占位符: - 正则表达式:`xuanhuan|dushi|wuxia` - 替换为:`分类` - 全局替换:勾选 或将 URL 中的分类 ID 替换为占位符: - 正则表达式:`/tags/(\d+)/` - 替换为:`/tags/分类/` ##### 应用结果 点击 **"应用到已选"** 后,系统会提示已更新的 URL 数量。修改结果会实时同步到预览区,可在导出 JSON 前确认格式正确。 ##### 批量修改 Layout 属性 除了 URL,还支持批量修改卡片的 Flexbox 布局属性: 1. 开启复选模式并选择目标卡片 2. 点击 **"批量改 layout"** 3. 勾选需要修改的属性并填写新值: - `layout_flexGrow` — 卡片拉伸权重(默认 `1`) - `layout_flexShrink` — 卡片收缩权重(默认 `0`) - `layout_alignSelf` — 自对齐方式(默认 `auto`) - `layout_flexBasisPercent` — 基础宽度百分比(`-1` 表示自动) - `layout_wrapBefore` — 是否在此卡片前换行 4. 点击 **"应用到已选"** 生效 ##### 样式模板管理 样式模板用于快速统一卡片的 Flexbox 布局风格,支持新增、编辑、删除和设置默认模板。 ###### 新增模板 1. 点击工具栏的 **"模板管理"** 按钮 2. 在弹窗中点击 **"新增模板"** 3. 填写模板名称(如"三列紧凑"、"两列宽屏"等),并设置各 layout 属性值: | 属性 | 说明 | 默认值 | |------|------|--------| | `layout_flexGrow` | 卡片拉伸权重,值越大占空间越多 | `1` | | `layout_flexShrink` | 空间不足时的收缩权重 | `0` | | `layout_alignSelf` | 自对齐方式(auto / flex-start / flex-end / center 等) | `auto` | | `layout_flexBasisPercent` | 基础宽度占总宽度的百分比,`-1` 表示自动等分 | `-1` | | `layout_wrapBefore` | 是否在此卡片前换行,可实现独占一行效果 | `false` | 4. 点击 **"保存模板"** ###### 模板管理与默认模板 在 **"模板管理"** 面板中: - **搜索**:顶部搜索框支持按模板名称快速过滤 - **查看**:点击"查看"展开模板的详细属性 - **编辑**:点击"编辑"修改模板名称和属性值 - **设默认**:点击"设默认"将该模板标记为默认,后续手动添加的卡片将自动应用此模板的布局属性 - **删除**:点击"删除"移除模板(至少保留一个) ###### 应用样式模板 1. 在发现页 URL 编辑器中,点击工具栏的 **"应用样式"** 按钮 2. 在下拉菜单中选择目标模板 3. 如果开启了复选模式,模板将应用到所有已勾选的卡片;否则应用到当前选中的单个卡片 4. 点击 **"应用到已选"** 生效 > **提示**:模板仅修改 layout 布局属性,不会覆盖卡片的标题和 URL。 ## 键盘快捷键 ### 规则页元素选择 | 按键 | 操作 | |------|------| | Esc | 退出选择模式 | | Enter | 确认选择(列表字段需选两次) | | ↑ | 移动到父元素 | | ↓ | 移动到第一个子元素 | | ← | 移动到上一个兄弟元素 | | → | 移动到下一个兄弟元素 | ### 发现页收集 | 按键 | 操作 | |------|------| | Enter | 完成收集 | ## 调试 ### 连接设置 打开阅读 APP → 我的 → Web服务 → 填入 IP 和端口号。 ### 调试关键字 | 格式 | 说明 | |------|------| | 普通文本 | 搜索 | | 分类名::URL | 发现 | | URL | 详情 | | ++URL | 目录 | | --URL | 正文 | 留空时默认关键字为"我的"。 ### 日志调试(输入 / 输出) **看输入** — 把这段加在规则最前面: ``` java.log("输入" + result);你的原规则 ``` **看输出** — 把这段加在规则最后面: ``` 你的原规则java.log("输出" + result); ``` > **向别人提问前一定要加上这两个再调试!!!** 调完删掉日志。 ### webView 是什么,什么时候开 **webView 的作用** 很多网站内容是动态加载的。不开 webView 时,规则可能抓不到最终页面内容。开了 webView,相当于"让页面先跑起来再抓"。 **什么时候建议开** - 规则看起来没错,但结果一直空 - 目录页、正文页总是抓不到 - 下一页链接存在,但翻页不生效 - 某字段不开拿不到,开了马上正常 **什么时候不要开** - 已经能正常抓到,就不要开 - 全字段都开会变慢,优先只开有问题的字段 **新手推荐顺序** 1. 先全部不开,先调规则 2. 哪个字段有问题,只给哪个字段开 webView > **一句话结论**:能不开就不开,出问题再精准开启。 ### 过 Cloudflare 盾 部分小说网站使用了 Cloudflare(CF)5 秒盾防护,直接请求会返回 403 并要求人机验证。扩展提供了「开启过 Cloudflare 盾」选项,勾选后会在导出的书源中自动注入 `loginCheckJs` 规则。 **工作原理** 1. 请求返回内容后,检测响应体是否包含 CF 验证特征(`_cf_`、`ge_ua`、`verify.php`)且状态码 ≥ 403 2. 如果命中 CF 盾,清除已有 Cookie,调用 `java.startBrowserAwait()` 打开浏览器完成人机验证 3. 验证通过后获取真实页面内容,继续正常解析 **什么时候需要开** - 调试时被cloudflare人机验证拦截,无法获取内容 - 普通请求能正常获取内容的网站**不需要开** ## 错误提示 选择器会自动检测潜在问题: - **Shadow DOM**:元素在 Shadow DOM 内,选择器可能不生效 - **Iframe**:跨域限制可能影响选择 - **动态 Class**:自动生成的 class 名称可能不稳定 - **空选择器**:未选择有效元素 - **无匹配**:选择器返回零个元素 ## 项目结构 ``` src/ # Chrome / Edge 版本 (MV3) ├── manifest.json # 扩展配置 ├── background.js # Service Worker(点击图标打开侧边栏) ├── content/ │ ├── picker.js # 元素选择器逻辑 │ └── picker.css # 选择器样式 ├── popup/ │ ├── index.html # 侧边栏界面 │ ├── popup.js # 侧边栏逻辑(规则页状态管理、导出) │ ├── popup.css # 侧边栏样式 │ ├── explore-url-editor.js # 发现页 URL 编辑器(收集、批量修改、样式模板) │ └── batch-url-utils.js # 批量 URL 替换工具(模板匹配 / 正则匹配) └── lib/ └── selector-generator.js # CSS 选择器生成算法 src-firefox/ # Firefox 版本 (MV2) ├── manifest.json # 扩展配置 ├── background.js # 后台脚本 ├── content/ │ ├── picker.js │ └── picker.css ├── popup/ │ ├── index.html │ ├── popup.js │ ├── explore-url-editor.js │ └── batch-url-utils.js └── lib/ └── selector-generator.js tests/ # 测试 └── batch-url-utils.test.js # 批量 URL 工具单元测试 ```