feat: 引入 so-novel submodule 并提供非交互下载工具
- vendor/so-novel: 上游 v1.12.0 (规则驱动的书源抓取/下载引擎) - tools/src: ToolMain 封装 search/download/toc/sources,stdout 只输出 JSON - tools/build.ps1: 自动定位/下载 JDK21,按平台显式激活 javet 原生库 profile - bin/novel.ps1|.cmd: 命令行入口(人读输出或 -Json) - SKILL.md/README.md: 使用说明与下载原理分析
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
---
|
||||
name: ebook-novel
|
||||
description: 用 so-novel 引擎聚合搜索多个中文小说书源并整本下载(txt/epub/html/pdf)。当用户要“找某本小说/下载小说/离线看/换个书源/转 epub/txt”时使用;本技能是本地 CLI 工具,不启动任何常驻服务。
|
||||
---
|
||||
|
||||
# 小说搜索与下载(so-novel)
|
||||
|
||||
本仓库把 [so-novel](https://github.com/freeok/so-novel) 作为 submodule 内嵌,并用 `bin\novel.ps1`
|
||||
封装成非交互 CLI。**不要**启动 so-novel 的 Web 模式(端口 7765),也**不要**去它的 TUI 菜单里操作。
|
||||
|
||||
## 什么时候用
|
||||
|
||||
- 用户给出书名/作者,想找可下载的书源或直接拿到整本文件;
|
||||
- 需要特定格式(txt / epub / html / pdf),或需要按章节验证书源是否完整;
|
||||
- 已有详情页链接,只想下载或看目录。
|
||||
|
||||
不适用:正版/付费平台(起点、微信读书等)的授权内容;无对应书源的外文小说。
|
||||
|
||||
## 标准流程
|
||||
|
||||
1. **搜索**(并发查全部激活书源,约 5–20 秒)
|
||||
```powershell
|
||||
pwsh bin\novel.ps1 search "<书名或作者>" -Limit 10 -Json
|
||||
```
|
||||
取 JSON 的 `results[]`(按相似度排序):`bookName` / `author` / `sourceName` / `url` / `latestChapter`。
|
||||
|
||||
2. **挑源**(关键,别拿到第一条就下)
|
||||
- 书名、作者与用户要求一致(注意同名续作、同人:「诡秘之主:瑶光」不是「诡秘之主」);
|
||||
- 同一本书多个源时,用 `toc` 比较章节数与首尾章节,取**章节最多、更新最近**的源;
|
||||
- 若某源 `latestChapter` 明显落后(几个月前),换源。
|
||||
|
||||
3. **验证目录**(可选但推荐,目录页反爬/改版会导致下出空书或残书)
|
||||
```powershell
|
||||
pwsh bin\novel.ps1 toc "<详情页链接>" -Json
|
||||
```
|
||||
看 `chapters` 数量和 `firstChapters` / `lastChapters`,两个常见异常信号:
|
||||
- **首章不是「第1章/序章」**(例如直接从“第101章”开始)→ 目录分页没抓全,会下出残书,换源;
|
||||
- **开头是「后记/尾声」、结尾是「第1章」** → 站点倒序且规则没声明 `desc`,成品章节会反序,换源。
|
||||
|
||||
4. **下载**
|
||||
```powershell
|
||||
pwsh bin\novel.ps1 download "<详情页链接>" -Ext txt -Json
|
||||
```
|
||||
默认落盘 `<仓库>\books\书名(作者).txt`;`-Ext epub` 生成带封面的 epub;`-Out` 可换目录。
|
||||
返回的 `file` 就是最终成品路径,`chapters` 是章节数,`ok=false` 时读 `error`。
|
||||
|
||||
5. **汇报**:给出书名、作者、来源站点、章节量级、文件绝对路径和大小;需要时说明换过几个源和原因。
|
||||
|
||||
## 输出契约
|
||||
|
||||
所有命令都是**一份 JSON**(`-Json`)或人读表格(默认):
|
||||
|
||||
```json
|
||||
{"ok":true,"command":"download","bookName":"...","author":"...",
|
||||
"sourceId":8,"sourceName":"笔趣阁365","ext":"txt",
|
||||
"file":"...\\books\\书名(作者).txt","bytes":1870447,"seconds":4.51}
|
||||
```
|
||||
|
||||
- 中文字段在 JSON 里是 `\uXXXX` 转义,解析后即为正确文本(这是为了绕开 Windows 控制台代码页)。
|
||||
- `search` 的 `sources.failed[]` 列出抓取失败的源及错误(`403`、超时等),`sources.empty` 是返回空的源数;
|
||||
这两个数字异常大说明网络/规则整体有问题,而不是这本书没有。
|
||||
|
||||
## 失败处理顺序
|
||||
|
||||
1. `search` 命中 0:换更完整的书名/作者,`-Limit` 调大,再试一次(不同源索引延迟不同)。
|
||||
2. 命中的 URL 下载失败(`ok=false` 或 `toc` 为空):**换另一个源的 URL**,不要在同一源重试多次。
|
||||
3. 连续多个源失败:加 `-Log` 看 `logTail` 里的上游报错,区分几种情况:
|
||||
- `403` / `Just a moment...` → Cloudflare 或封 UA,该源需要代理/`cf-bypass`,直接跳过;
|
||||
- 详情页书名或作者为空 → 站点改版,规则失效,跳过;
|
||||
- `源站章节目录为空` → 目录页反爬,跳过。
|
||||
4. 全书章节数正常但个别章节为空:上游允许单章失败跳过,成品仍可用;如实告知用户可能有缺章。
|
||||
|
||||
## 约束与礼貌
|
||||
|
||||
- 单机、串行使用;不要为了「快」把 `[crawl] concurrency` 调到 100,源站会限流并封 IP。
|
||||
- 不要并发跑多个 `download`;同一本书不要反复重下(`books/` 里已有就直接报告路径)。
|
||||
- 不要修改 `vendor/so-novel` 里的代码;需要新能力就加到 `tools/src/skills/novel/ToolMain.java`。
|
||||
- 上游更新后必须重建:`pwsh tools\build.ps1 -Force -RefreshRules`(详见 README 的维护章节)。
|
||||
|
||||
## 一次完整的例子
|
||||
|
||||
```powershell
|
||||
pwsh bin\novel.ps1 search "三体" -Limit 5 -Json
|
||||
# -> results 里 刘慈欣《三体1:地球往事》/ 笔趣阁52 / https://www.52bqg.com/book_40390/
|
||||
|
||||
pwsh bin\novel.ps1 toc "https://www.52bqg.com/book_40390/" -Json
|
||||
# -> chapters: 37,开头「第1章 1科学边界」,结尾「第37章 后记」——顺序正常
|
||||
|
||||
pwsh bin\novel.ps1 download "https://www.52bqg.com/book_40390/" -Ext txt -Json
|
||||
# -> file: D:\workbench\ebook-skill\books\三体1:地球往事(刘慈欣).txt
|
||||
```
|
||||
|
||||
对照:同一本书在「少年小说网」目录是倒序(开头“后记”、结尾“第1章”),下载会得到反序章节;
|
||||
若某个源的目录条数明显偏少、首章又不是第 1 章,说明分页没抓全,都会产出残书——这两种情况都应换源。
|
||||
Reference in New Issue
Block a user