ReadCat书源插件开发完全指南:三大接口一次讲透,让你想读什么就读什么

发布时间:2026/8/13 13:21:04
ReadCat书源插件开发完全指南:三大接口一次讲透,让你想读什么就读什么 ReadCat书源插件开发完全指南三大接口一次讲透让你想读什么就读什么【免费下载链接】read-cat一款免费、开源、简洁、纯净、无广告的小说阅读器项目地址: https://gitcode.com/gh_mirrors/re/read-cat你有没有过这样的瞬间装好一款小说阅读器满怀期待地搜一本冷门书结果页面转了几圈弹出没有找到相关内容而别人的同款阅读器里什么书都能搜到、能追更、能离线缓存。差别究竟在哪答案往往藏在四个字里——书源插件。ReadCat一款免费、开源、简洁、纯净、无广告的小说阅读器把从哪里取内容这件事完全开放了出来任何网站的小说只要有人为它写一个几十行的插件就能无缝接入阅读器。也就是说掌握ReadCat书源插件开发就等于给自己配了一把打开任意书库的钥匙。这篇文章不打算按部就班地念说明书而是模拟一次真实的开发闯关带你从零把第一个可用书源跑起来。一、先搞明白书源插件到底是个什么东西你可以把书源插件想象成一个翻译官。阅读器本身并不认识任何小说网站它只知道三件事要做搜书、看详情、读正文。书源插件的职责就是替阅读器向某个具体网站发出这三类请求再把网站返回的HTML翻译成阅读器能懂的数据格式。翻译的结果长什么样取决于一份约定俗成的契约。在ReadCat中这份契约就写在src/core/plugins/defined/booksource.d.ts里一个合格的书源只需要满足三个方法的签名interface BookSource { search: (searchkey: string) PromiseSearchEntity[]; getDetail: (detailPageUrl: string) PromiseDetailEntity; getTextContent: (chapter: Chapter) Promisestring[]; }是不是很直白搜书返回书名列表详情返回书籍信息和目录正文返回章节文本数组。后面所有工作都是围着这三个方法打转。二、闯关第一站把开发环境搭起来动手之前先确认手头有Node.js环境。接着在终端里把项目源码拉下来并安装依赖git clone https://gitcode.com/gh_mirrors/re/read-cat cd read-cat npm install依赖装完就够了吗还差一步热身。建议先启动项目确认能跑通再开始写插件否则后面排查问题时会分不清是环境问题还是代码问题。启动方式看package.json里的scripts即可。本关验收标准项目能正常启动你能在界面里找到设置 → 插件面板并且看到内置的Edge TTS引擎已就位。看到这个面板说明插件的加载链路是通的你已经站在了正确的起跑线上。三、闯关第二站搭出插件的骨架一个书源插件本质上就是一个JavaScript类。类是外壳类的静态属性负责报名信息构造函数里拿到的参数则是工具箱。先看报名信息。src/core/plugins/index.ts里的_isPlugin方法相当于体检中心任何插件导入前都要过一遍检查缺胳膊少腿的直接拒绝入场。体检项目包括ID16到32位只能由字母、数字、下划线、短横线组成相当于插件的身份证TYPE数字0代表书源1代表书城2代表TTS引擎GROUP / NAME分组名与展示名长度都有限制注意别起太长的名字VERSION / VERSION_CODE一个给人看的版本字符串一个用于程序比较的版本数字PLUGIN_FILE_URL插件文件的更新地址便于以后自动升级BASE_URL书源对应的站点域名书源类插件必须提供。再看工具箱。插件类被实例化时构造器会收到一个参数对象里面是ReadCat替你封装好的能力class MyBookSource { constructor({ request, store, cheerio, nanoid, uuid }) { // request.get / request.post发网络请求自动处理代理与编码 // store插件的私有存储可跨会话保存数据 // cheerio把HTML字符串变成可操作的DOM } }看到没连HTML解析库都给你备好了你真正要写的核心逻辑其实非常集中。四、闯关第三站实现三大核心能力4.1 搜索把关键词换成候选书单search(keyword)做的事很简单拼出搜索URL发起请求把结果列表翻译成SearchEntity。SearchEntity最少需要书名、作者和详情页链接三个字段封面和最新章节标题是可选项。async search(keyword) { const url ${this.baseUrl}/search?q${encodeURIComponent(keyword)}; const { body } await this.request.get(url); const $ this.cheerio.load(body); const results []; $(.book-item).each((_, el) { results.push({ bookname: $(el).find(.name).text().trim(), author: $(el).find(.author).text().trim(), detailPageUrl: $(el).find(a).attr(href), coverImageUrl: $(el).find(img).attr(src), latestChapterTitle: $(el).find(.latest).text().trim(), }); }); return results; }这里的关键套路是先看页面结构再写选择器。任何网站的搜索结果页打开浏览器开发者工具就能看到对应的DOM结构照着写即可。4.2 详情把一本书的骨架拉出来getDetail(detailPageUrl)接收搜索阶段拿到的详情页地址返回书籍信息外加整本目录。注意这里有个特殊的字段——chapterList它是一个章节数组每个章节形如{ title, url, index }。async getDetail(url) { const { body } await this.request.get(url); const $ this.cheerio.load(body); const chapterList []; $(.chapter-list a).each((index, el) { chapterList.push({ title: $(el).text().trim(), url: $(el).attr(href), index, }); }); return { bookname: $(h1).text().trim(), author: $(.author).text().trim(), coverImageUrl: $(.cover img).attr(src), intro: $(.intro).text().trim(), chapterList, }; }目录解析往往是全流程里最费神的一步有的网站分卷、有的分页、有的章节藏在JS动态渲染里。先挑目录结构简单的站点练手能少走很多弯路。4.3 正文把章节内容洗干净端上来getTextContent(chapter)拿到的就是chapterList里的某一项你要返回一个字符串数组数组里的每个元素会被渲染成一个段落。async getTextContent(chapter) { const { body } await this.request.get(chapter.url); const $ this.cheerio.load(body); const paragraphs []; $(#content p).each((_, el) { const text $(el).text().trim(); if (text) paragraphs.push(text); }); return paragraphs; }有个细节值得留意正文返回后ReadCat会统一做一次HTML消毒见src/core/plugins/index.ts中对getTextContent的包装空段落会被过滤掉。这既是安全兜底也提醒你返回的正文越干净阅读体验越好——那些请记住本站域名手机阅读请访问XX之类的广告尾巴尽量在解析时就直接滤掉。本关验收标准三个方法都写完了逻辑上能自洽——搜索能给出书详情能给出目录正文能给出段落。五、闯关第四站导入插件并跑通验证写好的插件是一段JS文本怎么让它被ReadCat认识有两条路路径一界面导入。进入设置 → 插件面板点击导入按钮选中你的my-book-source.js导入成功的插件会出现在列表里类型标签显示书源。路径二接口导入。在源码环境中可以直接调用插件管理器的入口方法把JS代码喂进去await GLOBAL_PLUGINS.importJSCode(jscode, { minify: true, enable: true });minify会压缩代码默认也会压缩enable决定导入后是否立即启用。导入失败的插件会进入失败列表并给出具体错误原因——这是排错的第一手资料。本关验收标准插件出现在列表中且状态为启用回到书架页搜索能搜到你写的那个站点的书点开能加载目录点进章节能看到正文。到这一步恭喜你已经正式解锁了自定义书源这个技能。六、避坑清单新手最容易栽的五个坑把高频翻车点整理成一张速查表对号入座即可静态属性不过检ID短于16位、GROUP超过15字符、BASE_URL没写http(s)://前缀导入直接失败。先看_isPlugin的校验规则再动手别凭感觉写。返回结构对不上search忘了返回detailPageUrl详情页跳不过去getDetail忘了拼chapterList目录永远空白。返回字段名一个都不能改。选择器写死网站改版后旧选择器失效这是书源失联的头号原因。解析逻辑尽量写健壮些并预留兜底选择器。忽略编码问题部分老站点返回的不是UTF-8乱码了别急着怀疑解析。request.get支持在配置里指定字符集先确认编码再写选择器。滥用存储插件的私有存储有4MB上限见store.ts中的PLUGIN_STORE_MAX_BYTE_LENGTH拿它当缓存时注意控制体积存到上限会抛错。七、再进一步从能用走向好用跑通第一个书源只是起点。往深了走还有三块值得探索的领地阅读体验打磨正文里的广告过滤规则、图片防盗链处理、分页章节的合并策略都能显著提升日常使用的舒适度插件类型拓展除了书源ReadCat还支持书城插件bookstore.d.ts和TTS语音引擎插件ttsengine.d.ts内置的Edge语音引擎就在src/core/plugins/built-in/tts/edge.ts是绝佳的参考范本调试工具链项目里带了插件开发工具包相关实现见src/core/plugin-devtools/与electron/plugin-devtools.ts在设置 → 插件的开发面板里导入工具包、设置端口并启动就能一边改代码一边实时验证效率翻倍。如果你想看插件系统如何在后台运转src/core/plugins/index.ts是整个插件的总调度室想知道插件数据如何持久化src/core/database/store/里的plugin-store.ts和plugins-jscode.ts给出了答案插件管理界面则位于src/components/settings/components/plugin/。结语你的第一行插件代码现在就值得开始回到开头的疑问——为什么别人的阅读器什么书都能看答案已经摆在你面前不是那款软件有什么魔法而是有人为它写了书源插件。现在轮到你给自己写一个了。不必追求一步到位先找一个结构简单的小说站点把搜索、详情、正文三个方法各写一个朴素版本导入、跑通、翻车、修好。当你第一次在自己写的书源里翻到正文的那一刻那种原来如此的踏实感就是最好的正反馈。今天就做一件事打开你的小说网站按F12看一眼它的搜索结果页结构然后在本地建一个空JS文件写下第一行class MyFirstBookSource {。剩下的交给好奇心和这篇指南。【免费下载链接】read-cat一款免费、开源、简洁、纯净、无广告的小说阅读器项目地址: https://gitcode.com/gh_mirrors/re/read-cat创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考