资讯动态

如何为Kotatsu-Redo编写新的漫画源解析器:Parsers库实战开发教程

发布时间:2026/10/23 2:06:46 来源:尧图企业网站定制
【免费下载链接】Kotatsu-RedoManga reader for Android项目地址https://gitcode.com/gh_mirrors/ko/Kotatsu-Redo点击查看免费下载Kotatsu-Redo是一款免费开源的 Android 漫画阅读器Manga reader for Android内置 1200 在线漫画源。它的核心设计是把抓取网站数据的工作从 App 本体中剥离出来交给独立的Parsers 解析器库完成。想给这款阅读器新增一个漫画网站源吗这篇教程将从架构、接口、开发到调试带你完整走一遍。1. 先搞懂架构为什么解析器单独放一个仓库Kotatsu-Redo 采用壳 解析器库的两层结构层级位置职责App 壳本项目Kotatsu-Redo阅读界面、书架、下载、同步、源管理等用户体验层Parsers 解析器库kotatsu-parsers-redo独立仓库每个漫画网站的 HTML/JSON 抓取与解析逻辑在 app/build.gradle 中可以看到App 通过 JitPack 依赖引入解析器库def parsersVersion libs.versions.parsers.get() implementation(com.github.clquwu:kotatsu-parsers-redo:$parsersVersion)版本号定义在 gradle/libs.versions.toml 中。这样做的好处网站改版了只需更新解析器仓库App 本身不用重新设计解析器代码也能在 PC 上用 JVM 直接跑测试不需要模拟器。CONTRIBUTING.md 也明确写道新增漫画源add a new manga source请去 parsers 仓库贡献而不是改 App 主仓库。2. App 如何认识一个新的解析器新源写好后App 侧需要三步才能生效这套机制可以从源码中清晰看到① 在MangaParserSource枚举中注册解析器库里的MangaParserSource是一个枚举每个枚举值对应一个漫画网站源。App 的源管理模块 MangaSourcesRepository.kt 直接读取该枚举构建全部可用源列表val allMangaSources: SetMangaParserSource ... MangaParserSource.entries.filterNotTo(it, MangaParserSource::isBroken)所以你的新源只要出现在枚举里就会自动被 App 发现、入库并出现在源管理界面中。② 工厂模式创建解析器实例用户点击某个源时App 通过 MangaRepository.kt 中的工厂为源创建对应的仓库对象is MangaParserSource - ParserMangaRepository( parser loaderContext.newParserInstance(source), cache contentCache, mirrorSwitcher mirrorSwitcher, )newParserInstance会通过反射在解析器库中找到你的解析类并实例化。③ 统一接口MangaRepository无论源多特殊App 只认 MangaRepository.kt 定义的这套接口——这也是解析器最终要回答的问题清单方法作用getList(offset, order, filter)按搜索词/筛选条件获取漫画列表getDetails(manga)获取漫画详情封面、作者、简介等getPages(chapter)获取某一章的所有页面getPageUrl(page)获取单页图片直链getFilterOptions()提供网站支持的高级筛选项作者、状态等getRelated(seed)获取相关推荐可选ParserMangaRepository.kt 展示了 App 如何调用解析器每个方法都被withMirrors { }包裹——如果配置了多镜像域名失败后会自动切换域名重试你写解析器时不必关心这些细节。3. 动手写一个解析器核心 5 步以下示例代码基于 parsers 库的MangaParser基类风格帮助你理解需要实现的内容完整模板以 parsers 仓库为准第一步定义源元信息在MangaParserSource枚举中新增一个条目声明源 ID、标题、主域名、支持的语言和类型// MangaParserSource.ktparsers 库 MY_FIRST_SOURCE( id 2024, // 唯一整数 ID决定本地数据隔离 title My Manga Site, domain www.example-manga.com, locale en, contentType ContentType.MANGA, ),第二步继承MangaParser声明基本信息class MyFirstParser : MangaParser() { override val source: MangaParserSource get() MangaParserSource.MY_FIRST_SOURCE override val id: Int 2024 override val name: String My Manga Site override val domain: String get() config[configKeyDomain] override val availableSortOrders setOf(SortOrder.UPDATED) }config/configKeyDomain由基类提供源设置如镜像域名、登录 Cookie会被持久化App 设置页 SourceSettingsFragment.kt 会自动渲染这些配置项。第三步实现漫画列表抓取getListoverride suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): ListManga { val query filter.query ?: return getListImpl(offset) val url https://$domain/search/?q${URLEncoder.encode(query, UTF-8)} val doc httpClient.get(url).document() return doc.select(.manga-item).map { Manga( source source, url it.select(a).attr(abs:href), title it.select(.title).text().trim(), cover it.select(img).attr(abs:src), ) } }httpClient是上下文注入的 OkHttpClient自动携带 Cookie、User-Agent 和代理设置直接拿来用即可。第四步实现详情与章节getDetailsoverride suspend fun getDetails(manga: Manga): Manga { val doc httpClient.get(manga.url).document() val author doc.select(.info .author).text().removePrefix(Author:).trim() val description doc.select(.description).text() val status if (doc.select(.status).text().contains(Finished)) Manga.Status.FINISHED else Manga.Status.ONGOING return manga.copy( author author, description description, status status, tags doc.select(.tags a).mapToSet { it.text() }, // 章节列表每个 MangaChapter 对应一章 chapters doc.select(.chapter-list li a).map { MangaChapter( source source, url it.attr(abs:href), title it.text().trim(), scanlator Example Scan, ) }, ) }第五步实现页面获取getPages与getPageUrloverride suspend fun getPages(chapter: MangaChapter): ListMangaPage { val doc httpClient.get(chapter.url).document() return doc.select(.reader img).mapToSequentialList { MangaPage( source source, url it.attr(abs:src), scanlator Example Scan, ) } } // 若 page.url 已是图片直链可不覆写基类默认返回 page.url override suspend fun getPageUrl(page: MangaPage): String page.url至此一个最小可用的解析器就完成了。剩下的交给 App 的 ParserMangaRepository.kt 去缓存、切换镜像和渲染界面。4. 用好MangaLoaderContext解析器能调用的工具箱MangaLoaderContext是 App 注入给解析器的能力集合。App 侧的实现类 MangaLoaderContextImpl.kt 展示了它背后接入了哪些系统能力对应到解析器可调用的高阶方法上下文能力实现典型用途httpClient/cookieJar自定义 OkHttpClient Cookie 管理常规请求、登录态保持evaluateJs(baseUrl, script)隐藏 WebView 执行 JS破解 JS 生成的页面数据、签名interceptWebViewRequestsWebView 请求拦截嗅探真实图片 API 地址MangaLoaderContextImpl.kt 可见完整参数requestBrowserAction抛出InteractiveActionRequiredException由 App 弹浏览器验证码、人机验证配合 CloudFlareActivity.kt 处理 CF 挑战encodeBase64/getPreferredLocales编解码与本地化图片 Base64 解码、多语言页面选择redrawImageResponse图片重绘去掉 CDN 防盗水印⚠️ 遇到 CloudFlare 防护时不要硬抓直接借助上下文的 CF 处理链路——App 已有现成的 CloudFlareInterceptor.kt 兜底。5. 调试技巧用内置 Test 源验证流程App 内置了一个专为解析器开发准备的试验田调试入口类 TestMangaRepository.kt 的每个方法都留了TODO(...)注释等于一份可运行的开发清单先实现getList→ 再实现getDetails→ 最后补getPages在 Debug/Nightly 构建中打开Settings → Debug由 DebugSettingsFragment.kt 的test_parser选项打开TestMangaSource的列表页即可不依赖真实网站测试整条数据链路仓库还附带了 androidTest 测试资产如 full.json供集成测试校验列表、章节、边界的解析正确性。推荐的开发循环在 parsers 仓库的 JVM 单元测试中跑通纯抓取逻辑速度快无需设备本地将 App 的parsersVersion指向你刚构建的 commit 版本进行真机验证按 CONTRIBUTING.md 的原则提交性能优先于代码美观、避免新增不必要依赖APK 体积很重要。6. 进阶让解析器更好用的加分项多镜像域名在onCreateConfig中为configKeyDomain提供多个候选域名App 的 MirrorSwitcher.kt 会在主域失败时自动切换逻辑见 ParserMangaRepository.kt 的withMirrors登录源实现MangaParserAuthProviderApp 会通过 SourceAuthActivity.kt 引导用户登录高级筛选覆写getFilterOptions与filterCapabilities把网站上的作者/状态/章节数筛选同步到 App 的筛选面板对应 FilterCoordinator.kt相关推荐覆写getRelatedManga点亮详情页的推荐模块。小结环节关键位置源注册parsers 库MangaParserSource枚举 → MangaSourcesRepository.kt实例化MangaRepository.kt接口契约MangaRepository.kt能力工具箱MangaLoaderContextImpl.kt调试清单TestMangaRepository.kt贡献规范CONTRIBUTING.md写解析器的本质就是把网站的漫画、章节、图片三样东西稳定地翻译 App 认识的Manga/MangaChapter/MangaPage三个对象。抓住这条主线其余的缓存、镜像、防护拦截都会由框架替你处理。现在就去 parsers 仓库写出属于你的第一个漫画源吧 赞分享【免费下载链接】Kotatsu-RedoManga reader for Android项目地址https://gitcode.com/gh_mirrors/ko/Kotatsu-Redo点击查看免费下载相关推荐养殖档案核对员实战指南用 agency-agents-zh 智能体审计畜禽养殖档案 Excel 与生产日报养殖档案核对员实战指南用 agency agents zh 智能体审计畜禽养殖档案 Excel 与生产日报 本文围绕 agency agents zh httStarling-LM-7B-alpha-openmind与OpenChat 3.5对比性能提升与技术创新Starling LM 7B alpha openmind与OpenChat 3.5对比性能提升与技术创新 Starling LM 7B alpha open上一篇聚类算法深度解析使用scikit-learn进行无监督学习下一篇DailyNotes数据安全详解AES加密与备份策略全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑