TypeScript AGPL-3.0

novel-downloader

一个可扩展的通用型小说下载器。

4

404-novel-project

Dernière activité 27 sept. 2026
404-novel-project/novel-downloader

2 k

étoiles

156

forks

5

issues ouvertes

novelnovel-downloader

Ce README est souvent en anglais.

小说下载器

一个可扩展的通用型小说下载器。

关于 404 小说文库项目

在这个 404 时代,由于种种原因,起点、晋江、刺猬猫、SF 等小说网站上的小说经常毫无征兆的消失。即使该小说已经入 V,即使你已经订阅了该小说。

这样的例子数不胜数。随便打开笔趣阁等转载网站,首发于起点,但现在起点上找不到该小说的情形比比皆是。像轻文轻小说这种整个网站都上天了的情况也不是没有。

如果小说消失时被笔趣阁等转载网站转载了,后来的读者尚且能一睹其风采,但如果小说发布的网站不是起点,小说也不够热,根本就没有转载网站转载,那后来者想一睹该小说的风采,就相当困难了。

404 小说文库项目的目的是:保存这些质量上乘,但不够热门,没有被其他网站转载,彻底从互联网上消失的作品。

本脚本为 404 小说文库项目的组成部分之一,对于无登录墙的小说网站,如您同意,本脚本将会尝试将当前书籍详情页及目录页(如果存在)存档至互联网档案馆(archive.org),以备日后(被删除后)查看。

存档过程中将会搜集并上报您如下信息:IP 地址、User-Agent、Referer、当前书籍详情页 URL、当前书籍目录页 URL(如果存在)、当前小说下载器脚本版本、当前脚本管理器版本。除上述信息外,不会搜集您任何其他信息。

安装

本软件为油猴脚本,需先在浏览器安装脚本管理器(Greasemonkey、Violentmonkey、Tampermonkey),再安装本脚本。具体可参见:如何安装用户脚本。

本脚本地址:

使用方法

本脚本执行下载任务时将播放无声音频,以保证脚本后台运行时不被休眠。

如果本脚本支持该小说网站,当打开小说目录页时,网页右上角会出现下载图标,点击该图标即可开始下载。

如果你要下载的小说章节较多,等待时间可能较长,此时请耐心等待。

你通过右下角进度条了解当前下载进度,或者按下 F12,打开网页控制台查看当前下载状态。

下载完成后,本脚本将会自动下载一个 TXT 文档及 EPUB 文件。

TXT 文档请使用记事本或其它阅读软件进行阅读。

EPUB 文件请使用相应阅读器阅读。

常见问题

特别提醒:请至本项目支持页面提交 issue, 发布于 greasyfork 评论区、交流群组等地方的反馈不会被处理。

  • Q:我在使用脚本时出现了 / 发现了问题。

    A:请在项目支持页面提交 issue 并按模板要求检查和填写所有信息。

    为生成详尽的日志,你需要在设置中启用调试模式。

    调试日志为下载生成的 zip 文件中的 debug.log 文件。如下载卡住,没有生成任何文件,你可以在设置中启用测试视图,而后复制日志选项卡中的所有内容并保存到txt文档后上传。

    如果我们未能复现你的问题,以及日志中没有相关问题的报错,可能需要你提供进一步的信息(某些问题可能和账号或网络环境有关)。

  • Q:希望支持某某网站。/希望增加某个功能。

    A:请在项目支持页面提交 issue 并按模板要求检查和填写所有信息。我们将视情况,酌情添加。

    需要注意的是,并不是所有的网站支持和新功能请求都会被满足,或者被立即满足。我们更欢迎贡献代码。

  • Q: 我在issue区中找到了和我反馈相重复的内容,我是否还要继续反馈。

    A:如果你反馈的是新网站或新功能请求,请直接在该issue下进行补充,重复的issue将被直接关闭。如果该issue已被关闭且未被实现,请不要再重复提交。

    对于bug,这些bug可能是曾经修复后又新出现的,可以根据具体情况决定是否开新issue。但你应当首先参考issue中的回复,一些bug可能无法在脚本中修复,但有其他解决方案,如ESJ EPUB下载问题(#690 )。

  • Q:请问有交流群组吗?

    A:有的。Matrix 空间:#404-novel-project:bgme.me,Telegram 群组:https://t.me/+ZCngCQiJ_xo2NDI1 。

目前支持小说网站(部分)

特别提醒:如欲下载支持列表中网站的付费章节,请登录相应网站帐户,并确定已购买相应付费章节。未登录网站帐户,或未购买的付费章节,下载时将直接忽略,无法进行下载。

站点 公共章节 付费章节 备注
SF 轻小说 ✅* ✅** *不支持对话小说,例:224282。 **VIP 章节仅支持图片版。
起点中文网 ✅ ✅ 部分小说 VIP 章节可能出现乱码无法下载。脚本支持 book.qidian.com 页面下载,但VIP章节因跨域问题需要切换至 www.qidian.com 下载。
起点女生网 ✅ ✅
晋江文学城 ✅ ✅ 晋江文学城章节下载可通过添加 API Token 以获得更好体验,Token 添加方法参见 Token 填写一节。
长佩文学 ✅ ✅ 反爬较严,限制下载速度,每分钟约可下载 6 章,请耐心等待,最好不要多开页面同时下载多本长佩小说。
长佩文学为单页应用,如打开书籍详情页右上角未出现下载图标,请按下 F5 重新加载当前页面。
书耽 ✅ ✅ VIP 章节仅支持图片版。
海棠文化线上文学城 ✅ ✅
次元姬 ✅ ✅
米国度 ✅ ✅
寒武纪年原创网 ✅ ✅
息壤中文网 ✅ ✅
有毒小说网 ✅ ✅
独阅读 ✅ ✅
轻之文库轻小说 ✅ ❌ VIP 章节仅支持 APP 查看
纵横中文网 ✅ ❌
花语女生网 ✅ ❌
17K 小说网 ✅ ❌
书海小说网 ✅ ❌
塔读文学 ✅ ❌
七猫中文网 ✅ ❌ 请先进入作品目录再运行脚本。
废文网 ✅ ❎ 部分小说或章节需登录后查看。
pixiv ✅ ❎ 单页应用,如打开书籍详情页右上角未出现下载图标,请按下 F5 重新加载当前页面。
Lofter ✅ ❎ 因本脚本会将博文中的图片也一同下载下来,对于图片特别多的博客,下载时请注意内存用量(800MB 限制),根据实际情况使用筛选函数分次下载。
部分博文内含视频内容,为节省内存使用,加快下载速度,本脚本将跳过视频内容。
如您使用广告屏蔽器,可能会影响本脚本在 Lofter 的工作。
努努书坊 ✅ ❎ 格式众多,如发现不支持页面敬请反馈。
真白萌 ✅ ❎
天涯书库 ✅ ❎
爱青果 ✅ ❎
カクヨム ✅ ❎
小説家になろう ✅ ❎
ハーメルン ✅ ❎
暁 ✅ ❎
ファンタジー小説 ✅ ❌
Novel Up Plus ✅ ❎
ESJ ✅ ❎ 脚本已自动修复 core-js 2.4.1 导致的 EPUB 下载报错(Cannot convert undefined or null to object),如仍遇问题请更新脚本至最新版本。
点击查看全部支持网站
站点 公共章节 付费章节 备注
番茄小说 ✅ ✅ 部分章节需要SVIP账号登录下载,否则会调用第三方API请求。
禁忌书屋 ✅ ❎
UU 看书网 ✅ ❎
亿软网 ✅ ❎ 网站性能差,降低抓取频率,请耐心等待。
书趣阁 ✅ ❎ 网站性能差,降低抓取频率,请耐心等待。
星空中文 ✅ ❎
乐文小说网 ✅ ❎
266 看书 ✅ ❎
和图书 ✅ ❎
阁笔趣 ✅ ❎
书书网 ✅ ❎
八一中文网 ✅ ❎ 抓取速度慢,请耐心等待。
完本神站 ✅ ❎
得间小说 ✅ ❎
轻小说文库 ✅ ❎
西方奇幻小说网 ✅ ❎
棉花糖小说网 ✅ ❎
笔趣阁 ✅ ❎
红叶书斋 ✅ ❎
哩哔轻小说 ✅ ❎ 因需要基于邻近章节修复隐藏链接的章节,生成目录时间变慢,大约2分钟。
落秋中文 ✅ ❎
一笔阁 ✅ ❎
腐书网 ✅ ❎
搜小说 ✅ ❎
腐国度 ✅ ❎
书包网 ✅ ❎
恋上你看书 ✅ ❎
同人小说网 ✅ ❎
同人圈 ✅ ❎
精品小说网 ✅ ❎
256 文学 ✅ ❎
笔趣阁小说网 ✅ ❎
海棠小说网 ✅ ❎ 部分文字被图片替换,请使用 HTML 版查看。
如需替换清理图片,请自行生成图片文字对照表。
笔趣阁 ✅ ❎
25 中文网 ✅ ❎
天域小说网 ✅ ❎
完本神站 ✅ ❎
燃文小说 ✅ ❎
望书阁 ✅ ❎
百合小说网 ✅ ❎
全书斋 ✅ ❎
蔷薇后花园 ✅ ❎
黑沼泽俱乐部 ✅ ❎
神凑轻小说 ✅ ❎
爱下书小说网 ✅ ❎
精彩小说网 ✅ ❎
爱下电子书 ✅ ❎
笔趣阁 ✅ ❎
言情小说 ✅ ❎
18 看书 ✅ ❎
笔下文学 333 ✅ ❎
小说屋 ✅ ❎
缤纷幻想 ✅ ❎
弟子小说网 ✅ ❎
新笔趣阁 ✅ ❎
69 书吧 ✅ ❎
笔下文学 ✅ ❎
飘天文学网 ✅ ❎
红袖招 ✅ ❎
38 看书 ✅ ❎
天天看小说 ✅ ❎
精华书阁 ✅ ❎
全职小说网 ✅ ❎ 网站反爬较严,大量抓取可能导致封禁ip。
笔趣阁 ✅ ❎
新笔趣阁 ✅ ❎
全本同人小说 ✅ ❎
鬼大爷网 ✅ ❎
69阅读 ✅ ❎
西瓜书屋 ✅ ❎ 部分文字会被图片替换,通过文件名映射、哈希映射、OCR识别三层解码。首次使用需下载PaddleOCR模型。

特殊权限说明

  • unsafeWindow:用于获取自定义筛选函数、自定义保存参数等设置。
  • GM_info/GM.info: 获取并输出脚本运行环境。
  • GM_xmlhttpRequest/GM.xmlHttpRequest:用于跨域 HTTP 请求。
  • GM_setValue/GM.setValue、GM_getValue/GM.getValue、GM_deleteValue/GM.deleteValue: 用于统计模块,本地统计运行次数。

OCR 图像文字识别

一些网站(比如西瓜书屋)为了防止文本被抓取,会把文字替换成图片。这个脚本针对这种情况做了专门的处理,采用了一套三步解码方案:

  1. 文件名映射:首先尝试根据图片文件名直接匹配对应的文字,这是最快的方法。
  2. 哈希映射:如果文件名匹配不到,就下载图片并计算哈希值来匹配,速度也比较快。

Note

文件名和哈希映射的匹配表会自动从(https://github.com/404-novel-project/novel-downloader-image-to-text-mapping )获取并保存在 Tampermonkey 的本地存储中。

  1. OCR识别:前两种方法都失败时,才会使用OCR(光学字符识别)来识别图片中的文字,这是最准确但也最慢的方法。注意,OCR识别也不能保证100%准确率。

Note

OCR功能使用的是PaddleOCR中文识别模型,模型文件会从GitHub自动下载并保存在Tampermonkey本地存储中。

字体匹配表

当前,晋江文学城和番茄小说下载可能需要你手动进行字体匹配操作。

如果你发现下载的小说文档有不正常的字符出现,可以打开设置-测试视图后点击日志或者按下F12启用开发者选项了解是否有提示字体匹配操作的信息,它们一般以“[jjwxc-font]”或者“[fanqie-font]”为开头。

你可以按照提示信息的内容,提交issue进行字体匹配的更新。请注意,相关信息不要提交到项目的issue中去,否则会被直接关闭。

Tips:对于晋江文学城一本小说中多个章节对应多个字体的情况,你可以复制日志中的所有内容,使用正则匹配(正则表达式:[a-zA-z]+://static.jjwxc.net/[^\s]*)来匹配所有的字体链接(可以使用在线匹配网站如:https://tool.oschina.net/regex# )。

Token 填写

当前部分网站(如晋江文学城)可能需要手动填写登录 token。app 平台一般为 Android 平台,其他平台一般不能使用(但也可以实践看看)。

抓包软件和教程

这里列举出一些常用的工具以供参考。

  1. 抓包精灵(Android)

下载抓包精灵/NetCapture(可在 Google Play、酷安搜索到,其他软件也可以)并配置好设置。

可参考 @ll0yiya 的经验(https://github.com/404-novel-project/novel-downloader/issues/599#issuecomment-1866142314)。

  1. HttpCanary(Android)

可参考 https://blog.csdn.net/weixin_53891182/article/details/124739048 等资料。

在编写脚本时,作者使用的版本:https://fin.lanzoub.com/iGYv20vym1dc。

  1. eCapture(Android)

需要 Android 内核版本 5.4以上。

详细信息,建议参考 https://mp.weixin.qq.com/s/KWm5d0uuzOzReRtr9PmuWQ 等资料。

  1. Charles(Windows / MacOS / Linux)

官网: https://www.charlesproxy.com/

需要电脑,可搭配 Android 模拟器。

可参考 https://blog.csdn.net/qq_41631913/article/details/135748992。

注:本节脚本代码中的值均为编撰,仅为示意。

晋江文学城

该网站现提供 2 个方法以获取 token 。

  1. 脚本设置获取
  • 在任意晋江小说页面加载完时打开设置,在“基本设置”选项卡中会看到“获取token”按钮(仅限第一次打开可见),点击按钮并关闭设置,按页面提示输入账号和密码后点击登录,如收到验证码则填入验证码后再次点击登录,如操作无误则可以看到返回的 token 值。

  • 该方法可能需要禁用主设备验证功能。如获取失败可根据提示重试、先在晋江 app 里重新登录后再试。如一直不能获取,则参考方法 2 。


  1. 自行抓取。
  • 要抓取的数据:
    • token: 登录晋江文学城 Android app 并随意浏览章节,在形如“https://app.jjwxc.org/androidapi/chapterContent?” 等链接中找到 &token= 后的字符串(止于下一个&)
    • (暂不需要,请忽略)user_key 方法同上,数据为 &user_key= 后的字符串(止于下一个&)

注:user_key对于部分账号可能是必须的,但目前脚本暂不需要该值,可不用抓取。如果你采用方法2,可以将两个一起抓取,未来可能有用。


成功抓取 token 后,在脚本管理器中新建如下脚本(不要把该脚本代码和其他脚本代码合并,除非你完全理解脚本的意思)并保存:

// ==UserScript==
// @name         auto inject tokenOptions
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  auto inject tokenOptions
// @author       You
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
  "use strict";

  const tokenOptions = {
    Jjwxc: "11111111_750afc84c839aaaaafccd841fffd11f1", //填入token,形如客户号+下划线'_'+字母与数字混合的字符串
  };
  window.tokenOptions = tokenOptions;
})();

如果你采用方法2,成功抓取 token 和 user_key 后,在脚本管理器中新建如下脚本(不要把该脚本代码和其他脚本代码合并,除非你完全理解脚本的意思)并保存:

// ==UserScript==
// @name         auto inject tokenOptions
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  auto inject tokenOptions
// @author       You
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
  "use strict";

  const tokenOptions = {
    Jjwxc: {
      token:"11111111_750afc84c839aaaaafccd841fffd11f1", //填入token,形如客户号+下划线'_'+字母与数字混合的字符串
      user_key:"11ffffff-11ff-11ff-11ff-111111111fff",//填入user_key
    }
  };
  window.tokenOptions = tokenOptions;
})();

Caution

在设置中启用调试模式以后,日志可能会输出一些包含 token 的链接,这个设计的初衷是为了更快定位发生的问题。

请不要直接将该日志上传到互联网上,当且仅当从事维护的开发者需要此日志定位问题时再提供(可以通过重新登录之前抓取 token 设备上的晋江 app 以使原 token 失效)。

息壤中文网

该网站的 Android app 启动时会检测 root 和 VPN 代理, 因此可能需要一些额外的操作以越过;此外 header 数据的获取需要安装CA证书,建议具有一定相关知识的人士进行操作。

需要抓取的数据:登录息壤中文网 Android app 并随意浏览章节,在形如“https://android-api.xrzww.com/api/readWithEncrypt”的网址中转到 Request header(即请求头)页,header 中的 deviceIdentify 和 Authorization 即为需要抓取的数据(注意不要弄成 Response header(响应头))。

在脚本管理器中新建如下脚本(不要把该脚本代码和其他脚本代码合并,除非你完全理解脚本的意思)并保存:

// ==UserScript==
// @name         auto inject tokenOptions
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  auto inject tokenOptions
// @author       You
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
  "use strict";

  const tokenOptions = {
    Xrzww: {
            deviceIdentify: "webh517657567560", //填入 header中的deviceIdentify值
            Authorization:  "Bearer 453453453e03ee546456546754756756", //填入 header中的Authorization值
        },
  };
  window.tokenOptions = tokenOptions;
})();

高阶使用技巧

启用调试功能

设置菜单中按击开启。

自定义下载设置

在设置面板中,选中“启用自定义下载设置”以使自定义下载参数生效。

以下是自定义下载参数的介绍:

  • 并行下载线程数:可以理解为同时下载的章节数量。数值需设置为 > 0 的整数。非法数值可能会导致下载出错。
  • 下载间隔:仅当“并行下载线程数” = 1时 生效。为每下载一章节后增加的下载间隔时间,单位为毫秒(1 秒= 1000 毫秒)。数值需设置为 > 0 的整数。
  • 最大下载间隔:仅当“并行下载线程数” = 1 时生效。为下载两章节之间最大的间隔时间,单位为毫秒(1 秒= 1000 毫秒)。数值需设置为 > 0 的整数。

该设置将应用于所有网站,一般不需要修改此设置,我们已经为每个网站设置好了比较合适的数值。但当网站添加反爬检测时,你可以使用本设置进行调整,我们也欢迎将新的数值提交到issue中。

自定义筛选函数

如欲只下载部分章节,请在点击运行按钮前,按下 F12 打开开发者工具,在 window 下创建 chapterFilter 函数,具体格式如下:

declare enum Status {
  pending = 0,
  downloading = 1,
  failed = 2,
  finished = 3,
  aborted = 4,
  saved = 5,
}
interface ChapterAdditionalMetadate {
  lastModified?: number;
}
declare class Chapter {
  bookUrl: string;
  bookname: string;
  chapterUrl: string;
  chapterNumber: number;
  chapterName: string | null;
  isVIP: boolean;
  isPaid: boolean | null;
  sectionName: string | null;
  sectionNumber: number | null;
  sectionChapterNumber: number | null;
  chapterParse: BaseRuleClass["chapterParse"];
  charset: string;
  options: object;
  status: Status;
  retryTime: number;
  contentRaw: HTMLElement | null;
  contentText: string | null;
  contentHTML: HTMLElement | null;
  contentImages: attachmentClass[] | null;
  additionalMetadate: ChapterAdditionalMetadate | null;
  chapterHtmlFileName: string | number;
  constructor(
    bookUrl: string,
    bookname: string,
    chapterUrl: string,
    chapterNumber: number,
    chapterName: string | null,
    isVIP: boolean,
    isPaid: boolean | null,
    sectionName: string | null,
    sectionNumber: number | null,
    sectionChapterNumber: number | null,
    chapterParse: BaseRuleClass["chapterParse"],
    charset: string,
    options: object
  );
  init(): Promise<this>;
  private parse;
}
declare class attachmentClass {
  url: string;
  name: string;
  mode: "naive" | "TM";
  headers?: {
    [index: string]: string;
  };
  private defaultHeader;
  status: Status;
  retryTime: number;
  imageBlob: Blob | null | void;
  constructor(imageUrl: string, name: string, mode: "naive" | "TM");
  init(): Promise<Blob | null>;
  private downloadImage;
  private tmDownloadImage;
}

interface chapterFilter {
  (chapter: Chapter): boolean;
}

自定义筛选函数示例:

只下载该本小说前 100 章内容:

function chapterFilter(chapter) {
  return chapter.chapterNumber <= 100;
}

只下载第一卷内容:

function chapterFilter(chapter) {
  return chapter.sectionNumber === 1;
}

只下载章节名称中含有“武器”的章节:

function chapterFilter(chapter) {
  return chapter.chapterName.includes("武器");
}

自定义保存参数

自定义保存参数允许您修改保存文件的样式,章节标题等内容。

使用方法大致同自定义筛选函数,即在 window 下创建 saveOptions 对象,具体格式如下:

interface SaveOptions {
  mainStyleText?: string;
  tocStyleText?: string;
  getchapterName?: Options["getchapterName"];
  //函数定义为:getchapterName(chapter: Chapter): string;
  genSectionText?: Options["genSectionText"];
  //函数定义为:genSectionText(sectionName: string): string;
  genChapterText?: Options["genChapterText"];
  //函数定义为:genChapterText(chapterName: string, contentText: string): string;
  genChapterEpub?: Options["genChapterEpub"];
  //函数定义为:genChapterEpub(contentXHTML: string):string;
  chapterSort?: Options["chapterSort"];
  //函数定义为:chapterSort(a: Chapter, b: Chapter): 0 | 1 | -1;
}

自定义保存参数示例:

将章节名称格式修改为 第xx章 xxxx :

const saveOptions = {
  getchapterName: (chapter) => {
    if (chapter.chapterName) {
      return `第${chapter.chapterNumber.toString()}章 ${chapter.chapterName}`;
    } else {
      return `第${chapter.chapterNumber.toString()}章`;
    }
  },
};
window.saveOptions = saveOptions;

更改 ZIP 文档中章节 HTML 文件样式:

const saveOptions = {
  mainStyleText: `p {
  text-indent: 4em;
  display: block;
  line-height: 1.3em;
  margin-top: 0.4em;
  margin-bottom: 0.4em;
}`,
};
window.saveOptions = saveOptions;

txt 文档每个自然段前加两个空格

const saveOptions = {
  genChapterText: (chapterName, contentText) => {
    contentText = contentText
      .split("\n")
      .map((line) => {
        if (line.trim() === "") {
          return line;
        } else {
          return line.replace(/^/, "    ");
        }
      })
      .join("\n");
    return `## ${chapterName}\n\n${contentText}\n\n`;
  },
};
window.saveOptions = saveOptions;

epub 文档删除章节空行

const saveOptions = {
  genChapterEpub: (contentXHTML) => {
    return contentXHTML.replaceAll("<p><br /></p>", "")
      .replaceAll("<p><br/></p>", "");
  },
};
window.saveOptions = saveOptions;

保存章节时倒序排列

const saveOptions = {
  chapterSort: (a, b) => {
    if (a.chapterNumber > b.chapterNumber) {
      return -1;
    }
    if (a.chapterNumber === b.chapterNumber) {
      return 0;
    }
    if (a.chapterNumber < b.chapterNumber) {
      return 1;
    }
    return 0;
  },
};
window.saveOptions = saveOptions;

使用用户脚本自动注入自定义保存参数:

如您总是想使用某一自定义保存参数,你可以使用如下用户脚本(根据实际需要修改相应数值),自动向页面注入自定义保存参数。

// ==UserScript==
// @name         auto inject saveOptions
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  auto inject saveOptions
// @author       You
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
  "use strict";

  const saveOptions = {
    getchapterName: (chapter) => {
      if (chapter.chapterName) {
        return `第${chapter.chapterNumber.toString()}章 ${chapter.chapterName}`;
      } else {
        return `第${chapter.chapterNumber.toString()}章`;
      }
    },
  };
  window.saveOptions = saveOptions;
})();

自定义筛选函数同理也可使用用户脚本自动注入。

自定义完成回调函数

interface customFinishCallback {
  (): void;
}

自定义完成回调函数将在下载完成并生成 ZIP 文件后自动执行。

使用自定义完成回调函数可在下载完成后自动完成某些工作,例如:关闭当前窗口。

function customFinishCallback(book: Book) {
  window.close();
}
window.customFinishCallback = customFinishCallback;

附录 完整的自定义脚本

// ==UserScript==
// @name         Noveldownloader Settings
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Noveldownloader Settings
// @author       You
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
  "use strict";

  // token 设置开始
  const tokenOptions = {
    Jjwxc: {
      token:"11111111_750afc84c839aaaaafccd841fffd11f1", //填入token,形如客户号+下划线'_'+字母与数字混合的字符串
      user_key:"11ffffff-11ff-11ff-11ff-111111111fff",//填入user_key
    },
    Xrzww: {
            deviceIdentify: "webh517657567560", //填入 header中的deviceIdentify值
            Authorization:  "Bearer 453453453e03ee546456546754756756", //填入 header中的Authorization值
        },
  };
  
  //token 设置结束

  // 章节过滤筛选开始
  function chapterFilter(chapter) {
    return chapter.chapterNumber <= 100;
  }
  //章节过滤筛选结束

  //保存设置开始
  const saveOptions = {
    getchapterName: (chapter) => {
      if (chapter.chapterName) {
        return `第${chapter.chapterNumber.toString()}章 ${chapter.chapterName}`;
      } else {
        return `第${chapter.chapterNumber.toString()}章`;
      } // 按 第i章 XXX 命名章节名字
    },
    genChapterEpub: (contentXHTML) => {
      return contentXHTML.replaceAll("<p><br /></p>", "")
        .replaceAll("<p><br/></p>", "");
    },
  };
  //保存设置结束

  if(saveOptions)
    window.saveOptions = saveOptions;
  if(tokenOptions)
  window.tokenOptions = tokenOptions;
  if(chapterFilter)
    window.chapterFilter = chapterFilter;
})();

开发

  1. git clone https://github.com/yingziwu/novel-downloader.git 将项目克隆至本地(访问 github 可能需要使用代理)。
  2. yarn install 安装依赖。
  3. 继承 BaseRuleClass 类,实现 bookParse、chapterParse 抽象方法,在 router/download.ts 文件中添加相应选择规则,在 header.json 文件 match 字段添加相应的匹配规则。
  4. yarn run build 编译生成最终脚本文件 dist/bundle.user.js。

License

AGPL-3.0

致谢

感谢 JetBrains 向本项目提供 WebStorm IDE。

Projets similaires

小说下载|网文下载 | 网络小说

Javaclicontent-exportdocument-parser
Ffreeok
8,3 k étoiles739

番茄小说下载器不精简版

Rust
Zzhongbai2333
3,9 k étoiles377

下载番茄小说

Python
Yying-ck
2,4 k étoiles260