剪藏#Riowang#剪藏

用 AI 一晚上撸了个自托管阅读器,兼容 Legado 5000+ 书源

2026 年 6 月 14 日1 分钟
分享Twitter / XTelegram微博
用 AI 一晚上撸了个自托管阅读器,兼容 Legado 5000+ 书源 封面

用 AI 一晚上撸了个自托管阅读器,兼容 Legado 5000+ 书源

NAS 上一直跑着 hectorqin/reader 当阅读器,能用,但越用越不爽:

  • UI 像 2015 年的产物,手机上看书体验很差

  • 没有 PWA,每次都要开浏览器找地址

  • TTS 朗读?不存在的

  • 想加个暗黑模式都得去改 Java 代码

既然手头有 AI 能写代码,不如自己从零搭一个。一晚上干完,从书源引擎到前端阅读器到 CI/CD 自动部署,全链路跑通。

目标:兼容 Legado 书源,但不复刻 Legado

Legado(阅读 App)的生态里有 5000+ 社区维护的书源,格式是 JSON,里面定义了"去哪搜索、怎么提取书名、怎么拿章节列表、怎么取正文"的规则。

现有方案(hectorqin/reader)的思路是用 Java 复刻 Legado 的规则引擎。我换了个策略:

读 Legado 格式,用 Python 自己执行。

不去复刻 Legado 的 java.* bridge 全集,而是用 Python 生态的解析库直接处理:

CSS 选择器 @css:div.title BeautifulSoup4
JSOUP 简写 class.name@tag.a@href 自写适配层
XPath //div[@class="content"] lxml
JSONPath $.data.list[*].title jsonpath-ng
正则 ##作者:(.+) Python re
JavaScript <js>result.replace(...)</js> QuickJS 沙盒

这样做的好处是:70% 以上的书源用简单选择器就能跑通,不需要完整的 JS bridge。剩下那些复杂的(加密、动态分页)后续再加。

技术栈:一个 Docker 容器搞定

JAVASCRIPT
后端:Python + FastAPI + SQLite + httpx
前端:React + TypeScript + Tailwind + PWA
部署:Docker 单容器,NAS 一键跑

为什么选 Python 不用 Java/Kotlin?

  1. 解析库生态好——BS4、lxml、jsonpath-ng 都是成熟工具

  2. 异步 I/O 原生支持——搜索时并发请求几十个书源

  3. 写起来快——一晚上要干完,不想写模板代码

为什么单容器?NAS 上跑 Docker,一个镜像包含前后端所有东西,docker run 一行命令启动,不搞 docker-compose 多服务那套。

核心能力

1. 搜索:流式返回,不等超时

267 个书源并发搜索,不可能等所有都返回再显示——有些站早就挂了,等它超时要 15 秒。

我用 SSE(Server-Sent Events)做流式推送:每个书源一返回结果就立刻推给前端,页面实时刷新。

JAVASCRIPT
用户输入关键词
  → 后端并发请求 267 个书源(信号量限制 10 并发)
  → 书源 A 返回 → 立即推送 → 前端追加显示
  → 书源 B 返回 → 立即推送 → 前端追加显示
  → ...
  → 全部完成或超时 → 发送 [DONE]

体感差异很大:从"等 15 秒看到一堆结果"变成"1 秒就开始出结果,持续刷新"。

2. 规则引擎:处理 Legado 的奇葩语法

Legado 的规则语法在 JSON 里写得很随意,各种换行、嵌套、组合:

JAVASCRIPT
// 先取 JSONPath,再正则替换
$.groupID##.*_##

// URL 模板引用已解析的字段
https://api.example.com/chapters?id={{book.kind}}

// 按文本内容查找元素
text.在线阅读@href

这些都不是标准语法,需要一个一个适配。我的引擎做了:

  • ## 内联正则:$.field##regex##replacement

  • {{book.field}} 模板变量:URL 里引用其他已解析字段

  • text.xxx 选择器:按文本内容查找 DOM 元素

  • 自动 Referer:很多 API 验证来源,自动加上目标域名的 Referer

  • URL 清理:Legado JSON 里的 URL 经常有换行符、相对路径,全部自动修正

3. 前端:响应式 + PWA

一套代码适配手机和桌面:

  • 手机:全屏沉浸阅读,底部导航

  • 桌面:侧边章节栏 + 居中阅读区

PWA 支持意味着可以"添加到主屏幕"当独立 App 用,不需要每次打开浏览器输地址。

阅读设置:字号、行距、主题(亮色/暗色/护眼)都可以调。

CI/CD:push 即部署

整条流水线全自动:

JAVASCRIPT
git push main
  → GitHub Actions 构建 Docker 镜像
  → 推送到 Docker Hub
  → SSHNAS(通过 Cloudflare Tunnel)
  → docker pull + restart

从提交代码到 NAS 上跑起新版本,大概 30 秒。改一行代码,手机刷新就能看到效果。

JAVASCRIPT
# .github/workflows/deploy.yml 核心步骤
- name: Build and push
  uses: docker/build-push-action@v6
  with:
    tags: rio22/reader:latest

- name: Deploy to NAS
  run: |
    ssh "$NAS_USER@$NAS_HOST" "docker pull rio22/reader:latest && \
      docker stop reader; docker rm reader; \
      docker run -d --name reader -p 8880:8080 rio22/reader:latest"

SSH 走的是 Cloudflare Tunnel(没有公网 IP),GitHub Actions 里装了 cloudflared 做代理。

部署:一行命令

JAVASCRIPT
docker run -d \
  --name reader \
  --restart unless-stopped \
  -p 8880:8080 \
  -v /volume1/docker/reader/data:/app/data \
  rio22/reader:latest

-p 8880:8080 外部端口 8880 映射到容器 8080,按需改
-v .../data:/app/data 数据持久化(SQLite + 缓存),路径改成你的
rio22/reader:latest Docker Hub 镜像,push main 自动构建

启动后访问 http://NAS-IP:8880,在"书源"页面贴入书源 JSON 地址即可导入。推荐用这个(约 270 个源):

JAVASCRIPT
https://cdn.jsdelivr.net/gh/tickmao/Novel@master/sources/legado/full.json

实际效果

搜索"十日终焉":

  • 0.5 秒开始出结果

  • 最终 122 条,来自多个书源

  • 点开第一条:1496 章

  • 点击章节:正文 2345 字,排版干净

对比 hectorqin/reader:

语言 Java/Kotlin Python + React
UI 传统服务端渲染 现代 SPA + PWA
搜索体验 等全部加载 SSE 流式实时
手机适配 勉强能用 响应式原生体验
部署 docker-compose 单容器
开发效率 改 Java 重编译 热重载秒级反馈

踩的坑

1. 书源 URL 里有换行符

Legado 的 JSON 文件里,searchUrl 字段经常有 \n,导致 HTTP 请求直接报错。加了一行 .replace("\n", "") 解决。

2. 相对路径 URL

很多书源的 searchUrl 写的是 /search?q=xxx 而不是完整 URL。需要自动拼接书源域名。

3. Referer 验证

不少 API(QQ 阅读等)会验证 Referer 头。之前没加,返回 "incorrect referer"。现在所有请求自动带上目标域名作为 Referer。

4. 缓存了错误响应

早期请求失败的响应被缓存了,后来修了代码但结果不变。加了"小于 50 字不缓存"的规则防止脏缓存。

5. 通过隧道操作隧道本身

CI 部署时 SSH 走 Cloudflare Tunnel。如果操作不当把隧道搞断了,就连不上 NAS 了。(这个坑我之前单独写过一篇)

功能状态

书源导入(URL / 文件) ✅ 已完成 兼容 Legado JSON 格式
多源搜索 ✅ 已完成 SSE 流式输出,实时显示
章节列表 ✅ 已完成 支持分页目录
正文阅读(滚动模式) ✅ 已完成 字号/行距/主题可调
响应式布局 ✅ 已完成 手机/桌面自适应
PWA 安装 ✅ 已完成 可添加到主屏幕
Docker 一键部署 ✅ 已完成 单容器 + CI/CD 自动构建
翻页模式 🚧 未完成 左右滑动模拟纸书
漫画阅读 🚧 未完成 条漫 + 页漫双模式
整本下载 / 离线缓存 🚧 未完成 IndexedDB 客户端存储
导出 epub / txt 🚧 未完成 后端生成,前端触发下载
TTS 朗读 🚧 未完成 Edge TTS + 句子高亮
书架管理 🚧 未完成 收藏、分类、更新检测
复杂 JS 书源 🚧 未完成 完整 java.* bridge

代码开源在 GitHub:https://github.com/riowang88/reader

一句话总结

兼容 Legado 书源格式 + Python 自建执行引擎 + React PWA 前端 + Docker 单容器部署 = 一个能用的自托管阅读器,一晚上从零到部署上线。

如果你也在 NAS 上找阅读方案,可以试试。书源直接用 Legado 社区的,不用重新找。

原文地址: https://mp.weixin.qq.com/s?__biz=MzIzOTg5NTg3Mw==&mid=2247484726&idx=1&sn=0bbcf601fc137a7a2e9716d9375ca779&chksm=e8f441373756f0254e8931d90fcc135c90d6cae0fce6c733c269013bb3449effae7ad115e15a&mpshare=1&scene=1&srcid=0614QJAKSAsZNqz7g2Bi5KXa&sharer_shareinfo=e495e2129b0cea7f97a3f5378806a8f8&sharer_shareinfo_first=e495e2129b0cea7f97a3f5378806a8f8#rd

相关文章