novel-downloader 1.4.5__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- novel_downloader/__init__.py +1 -1
- novel_downloader/cli/__init__.py +2 -4
- novel_downloader/cli/clean.py +21 -88
- novel_downloader/cli/config.py +27 -104
- novel_downloader/cli/download.py +78 -66
- novel_downloader/cli/export.py +20 -21
- novel_downloader/cli/main.py +3 -1
- novel_downloader/cli/search.py +120 -0
- novel_downloader/cli/ui.py +156 -0
- novel_downloader/config/__init__.py +10 -14
- novel_downloader/config/adapter.py +195 -99
- novel_downloader/config/{loader.py → file_io.py} +53 -27
- novel_downloader/core/__init__.py +14 -13
- novel_downloader/core/archived/deqixs/fetcher.py +115 -0
- novel_downloader/core/archived/deqixs/parser.py +132 -0
- novel_downloader/core/archived/deqixs/searcher.py +89 -0
- novel_downloader/core/archived/qidian/searcher.py +79 -0
- novel_downloader/core/archived/wanbengo/searcher.py +98 -0
- novel_downloader/core/archived/xshbook/searcher.py +93 -0
- novel_downloader/core/downloaders/__init__.py +8 -30
- novel_downloader/core/downloaders/base.py +182 -30
- novel_downloader/core/downloaders/common.py +217 -384
- novel_downloader/core/downloaders/qianbi.py +332 -4
- novel_downloader/core/downloaders/qidian.py +250 -290
- novel_downloader/core/downloaders/registry.py +69 -0
- novel_downloader/core/downloaders/signals.py +46 -0
- novel_downloader/core/exporters/__init__.py +8 -26
- novel_downloader/core/exporters/base.py +107 -31
- novel_downloader/core/exporters/common/__init__.py +3 -4
- novel_downloader/core/exporters/common/epub.py +92 -171
- novel_downloader/core/exporters/common/main_exporter.py +14 -67
- novel_downloader/core/exporters/common/txt.py +90 -86
- novel_downloader/core/exporters/epub_util.py +184 -1327
- novel_downloader/core/exporters/linovelib/__init__.py +3 -2
- novel_downloader/core/exporters/linovelib/epub.py +165 -222
- novel_downloader/core/exporters/linovelib/main_exporter.py +10 -71
- novel_downloader/core/exporters/linovelib/txt.py +76 -66
- novel_downloader/core/exporters/qidian.py +15 -11
- novel_downloader/core/exporters/registry.py +55 -0
- novel_downloader/core/exporters/txt_util.py +67 -0
- novel_downloader/core/fetchers/__init__.py +57 -56
- novel_downloader/core/fetchers/aaatxt.py +83 -0
- novel_downloader/core/fetchers/{biquge/session.py → b520.py} +10 -10
- novel_downloader/core/fetchers/{base/session.py → base.py} +63 -47
- novel_downloader/core/fetchers/biquyuedu.py +83 -0
- novel_downloader/core/fetchers/dxmwx.py +110 -0
- novel_downloader/core/fetchers/eightnovel.py +139 -0
- novel_downloader/core/fetchers/{esjzone/session.py → esjzone.py} +23 -11
- novel_downloader/core/fetchers/guidaye.py +85 -0
- novel_downloader/core/fetchers/hetushu.py +92 -0
- novel_downloader/core/fetchers/{qianbi/browser.py → i25zw.py} +22 -26
- novel_downloader/core/fetchers/ixdzs8.py +113 -0
- novel_downloader/core/fetchers/jpxs123.py +101 -0
- novel_downloader/core/fetchers/{biquge/browser.py → lewenn.py} +15 -15
- novel_downloader/core/fetchers/{linovelib/session.py → linovelib.py} +16 -12
- novel_downloader/core/fetchers/piaotia.py +105 -0
- novel_downloader/core/fetchers/qbtr.py +101 -0
- novel_downloader/core/fetchers/{qianbi/session.py → qianbi.py} +9 -9
- novel_downloader/core/fetchers/{qidian/session.py → qidian.py} +55 -40
- novel_downloader/core/fetchers/quanben5.py +92 -0
- novel_downloader/core/fetchers/{base/rate_limiter.py → rate_limiter.py} +2 -2
- novel_downloader/core/fetchers/registry.py +60 -0
- novel_downloader/core/fetchers/{sfacg/session.py → sfacg.py} +11 -9
- novel_downloader/core/fetchers/shencou.py +106 -0
- novel_downloader/core/fetchers/{common/browser.py → shuhaige.py} +24 -19
- novel_downloader/core/fetchers/tongrenquan.py +84 -0
- novel_downloader/core/fetchers/ttkan.py +95 -0
- novel_downloader/core/fetchers/{common/session.py → wanbengo.py} +21 -17
- novel_downloader/core/fetchers/xiaoshuowu.py +106 -0
- novel_downloader/core/fetchers/xiguashuwu.py +177 -0
- novel_downloader/core/fetchers/xs63b.py +171 -0
- novel_downloader/core/fetchers/xshbook.py +85 -0
- novel_downloader/core/fetchers/{yamibo/session.py → yamibo.py} +23 -11
- novel_downloader/core/fetchers/yibige.py +114 -0
- novel_downloader/core/interfaces/__init__.py +8 -14
- novel_downloader/core/interfaces/downloader.py +6 -2
- novel_downloader/core/interfaces/exporter.py +7 -7
- novel_downloader/core/interfaces/fetcher.py +4 -17
- novel_downloader/core/interfaces/parser.py +5 -6
- novel_downloader/core/interfaces/searcher.py +26 -0
- novel_downloader/core/parsers/__init__.py +58 -22
- novel_downloader/core/parsers/aaatxt.py +132 -0
- novel_downloader/core/parsers/b520.py +116 -0
- novel_downloader/core/parsers/base.py +63 -12
- novel_downloader/core/parsers/biquyuedu.py +133 -0
- novel_downloader/core/parsers/dxmwx.py +162 -0
- novel_downloader/core/parsers/eightnovel.py +224 -0
- novel_downloader/core/parsers/{esjzone/main_parser.py → esjzone.py} +67 -67
- novel_downloader/core/parsers/guidaye.py +128 -0
- novel_downloader/core/parsers/hetushu.py +139 -0
- novel_downloader/core/parsers/i25zw.py +137 -0
- novel_downloader/core/parsers/ixdzs8.py +186 -0
- novel_downloader/core/parsers/jpxs123.py +137 -0
- novel_downloader/core/parsers/lewenn.py +142 -0
- novel_downloader/core/parsers/{linovelib/main_parser.py → linovelib.py} +54 -65
- novel_downloader/core/parsers/piaotia.py +189 -0
- novel_downloader/core/parsers/qbtr.py +136 -0
- novel_downloader/core/parsers/{qianbi/main_parser.py → qianbi.py} +54 -51
- novel_downloader/core/parsers/qidian/__init__.py +2 -2
- novel_downloader/core/parsers/qidian/book_info_parser.py +58 -59
- novel_downloader/core/parsers/qidian/chapter_encrypted.py +290 -346
- novel_downloader/core/parsers/qidian/chapter_normal.py +25 -56
- novel_downloader/core/parsers/qidian/main_parser.py +19 -57
- novel_downloader/core/parsers/qidian/utils/__init__.py +12 -11
- novel_downloader/core/parsers/qidian/utils/decryptor_fetcher.py +6 -7
- novel_downloader/core/parsers/qidian/utils/fontmap_recover.py +143 -0
- novel_downloader/core/parsers/qidian/utils/helpers.py +0 -4
- novel_downloader/core/parsers/qidian/utils/node_decryptor.py +2 -2
- novel_downloader/core/parsers/quanben5.py +103 -0
- novel_downloader/core/parsers/registry.py +57 -0
- novel_downloader/core/parsers/{sfacg/main_parser.py → sfacg.py} +46 -48
- novel_downloader/core/parsers/shencou.py +215 -0
- novel_downloader/core/parsers/shuhaige.py +111 -0
- novel_downloader/core/parsers/tongrenquan.py +116 -0
- novel_downloader/core/parsers/ttkan.py +132 -0
- novel_downloader/core/parsers/wanbengo.py +191 -0
- novel_downloader/core/parsers/xiaoshuowu.py +173 -0
- novel_downloader/core/parsers/xiguashuwu.py +435 -0
- novel_downloader/core/parsers/xs63b.py +161 -0
- novel_downloader/core/parsers/xshbook.py +134 -0
- novel_downloader/core/parsers/yamibo.py +155 -0
- novel_downloader/core/parsers/yibige.py +166 -0
- novel_downloader/core/searchers/__init__.py +51 -0
- novel_downloader/core/searchers/aaatxt.py +107 -0
- novel_downloader/core/searchers/b520.py +84 -0
- novel_downloader/core/searchers/base.py +168 -0
- novel_downloader/core/searchers/dxmwx.py +105 -0
- novel_downloader/core/searchers/eightnovel.py +84 -0
- novel_downloader/core/searchers/esjzone.py +102 -0
- novel_downloader/core/searchers/hetushu.py +92 -0
- novel_downloader/core/searchers/i25zw.py +93 -0
- novel_downloader/core/searchers/ixdzs8.py +107 -0
- novel_downloader/core/searchers/jpxs123.py +107 -0
- novel_downloader/core/searchers/piaotia.py +100 -0
- novel_downloader/core/searchers/qbtr.py +106 -0
- novel_downloader/core/searchers/qianbi.py +165 -0
- novel_downloader/core/searchers/quanben5.py +144 -0
- novel_downloader/core/searchers/registry.py +79 -0
- novel_downloader/core/searchers/shuhaige.py +124 -0
- novel_downloader/core/searchers/tongrenquan.py +110 -0
- novel_downloader/core/searchers/ttkan.py +92 -0
- novel_downloader/core/searchers/xiaoshuowu.py +122 -0
- novel_downloader/core/searchers/xiguashuwu.py +95 -0
- novel_downloader/core/searchers/xs63b.py +104 -0
- novel_downloader/locales/en.json +36 -79
- novel_downloader/locales/zh.json +37 -80
- novel_downloader/models/__init__.py +23 -50
- novel_downloader/models/book.py +44 -0
- novel_downloader/models/config.py +16 -43
- novel_downloader/models/login.py +1 -1
- novel_downloader/models/search.py +21 -0
- novel_downloader/resources/config/settings.toml +39 -74
- novel_downloader/resources/css_styles/intro.css +83 -0
- novel_downloader/resources/css_styles/main.css +30 -89
- novel_downloader/resources/json/xiguashuwu.json +718 -0
- novel_downloader/utils/__init__.py +43 -0
- novel_downloader/utils/chapter_storage.py +247 -226
- novel_downloader/utils/constants.py +5 -50
- novel_downloader/utils/cookies.py +6 -18
- novel_downloader/utils/crypto_utils/__init__.py +13 -0
- novel_downloader/utils/crypto_utils/aes_util.py +90 -0
- novel_downloader/utils/crypto_utils/aes_v1.py +619 -0
- novel_downloader/utils/crypto_utils/aes_v2.py +1143 -0
- novel_downloader/utils/{crypto_utils.py → crypto_utils/rc4.py} +3 -10
- novel_downloader/utils/epub/__init__.py +34 -0
- novel_downloader/utils/epub/builder.py +377 -0
- novel_downloader/utils/epub/constants.py +118 -0
- novel_downloader/utils/epub/documents.py +297 -0
- novel_downloader/utils/epub/models.py +120 -0
- novel_downloader/utils/epub/utils.py +179 -0
- novel_downloader/utils/file_utils/__init__.py +5 -30
- novel_downloader/utils/file_utils/io.py +9 -150
- novel_downloader/utils/file_utils/normalize.py +2 -2
- novel_downloader/utils/file_utils/sanitize.py +2 -7
- novel_downloader/utils/fontocr.py +207 -0
- novel_downloader/utils/i18n.py +2 -0
- novel_downloader/utils/logger.py +10 -16
- novel_downloader/utils/network.py +111 -252
- novel_downloader/utils/state.py +5 -90
- novel_downloader/utils/text_utils/__init__.py +16 -21
- novel_downloader/utils/text_utils/diff_display.py +6 -9
- novel_downloader/utils/text_utils/numeric_conversion.py +253 -0
- novel_downloader/utils/text_utils/text_cleaner.py +179 -0
- novel_downloader/utils/text_utils/truncate_utils.py +62 -0
- novel_downloader/utils/time_utils/__init__.py +6 -12
- novel_downloader/utils/time_utils/datetime_utils.py +23 -33
- novel_downloader/utils/time_utils/sleep_utils.py +5 -10
- novel_downloader/web/__init__.py +13 -0
- novel_downloader/web/components/__init__.py +11 -0
- novel_downloader/web/components/navigation.py +35 -0
- novel_downloader/web/main.py +66 -0
- novel_downloader/web/pages/__init__.py +17 -0
- novel_downloader/web/pages/download.py +78 -0
- novel_downloader/web/pages/progress.py +147 -0
- novel_downloader/web/pages/search.py +329 -0
- novel_downloader/web/services/__init__.py +17 -0
- novel_downloader/web/services/client_dialog.py +164 -0
- novel_downloader/web/services/cred_broker.py +113 -0
- novel_downloader/web/services/cred_models.py +35 -0
- novel_downloader/web/services/task_manager.py +264 -0
- novel_downloader-2.0.0.dist-info/METADATA +171 -0
- novel_downloader-2.0.0.dist-info/RECORD +210 -0
- {novel_downloader-1.4.5.dist-info → novel_downloader-2.0.0.dist-info}/entry_points.txt +1 -1
- novel_downloader/config/site_rules.py +0 -94
- novel_downloader/core/downloaders/biquge.py +0 -25
- novel_downloader/core/downloaders/esjzone.py +0 -25
- novel_downloader/core/downloaders/linovelib.py +0 -25
- novel_downloader/core/downloaders/sfacg.py +0 -25
- novel_downloader/core/downloaders/yamibo.py +0 -25
- novel_downloader/core/exporters/biquge.py +0 -25
- novel_downloader/core/exporters/esjzone.py +0 -25
- novel_downloader/core/exporters/qianbi.py +0 -25
- novel_downloader/core/exporters/sfacg.py +0 -25
- novel_downloader/core/exporters/yamibo.py +0 -25
- novel_downloader/core/factory/__init__.py +0 -20
- novel_downloader/core/factory/downloader.py +0 -73
- novel_downloader/core/factory/exporter.py +0 -58
- novel_downloader/core/factory/fetcher.py +0 -96
- novel_downloader/core/factory/parser.py +0 -86
- novel_downloader/core/fetchers/base/__init__.py +0 -14
- novel_downloader/core/fetchers/base/browser.py +0 -403
- novel_downloader/core/fetchers/biquge/__init__.py +0 -14
- novel_downloader/core/fetchers/common/__init__.py +0 -14
- novel_downloader/core/fetchers/esjzone/__init__.py +0 -14
- novel_downloader/core/fetchers/esjzone/browser.py +0 -204
- novel_downloader/core/fetchers/linovelib/__init__.py +0 -14
- novel_downloader/core/fetchers/linovelib/browser.py +0 -193
- novel_downloader/core/fetchers/qianbi/__init__.py +0 -14
- novel_downloader/core/fetchers/qidian/__init__.py +0 -14
- novel_downloader/core/fetchers/qidian/browser.py +0 -318
- novel_downloader/core/fetchers/sfacg/__init__.py +0 -14
- novel_downloader/core/fetchers/sfacg/browser.py +0 -189
- novel_downloader/core/fetchers/yamibo/__init__.py +0 -14
- novel_downloader/core/fetchers/yamibo/browser.py +0 -229
- novel_downloader/core/parsers/biquge/__init__.py +0 -10
- novel_downloader/core/parsers/biquge/main_parser.py +0 -134
- novel_downloader/core/parsers/common/__init__.py +0 -13
- novel_downloader/core/parsers/common/helper.py +0 -323
- novel_downloader/core/parsers/common/main_parser.py +0 -106
- novel_downloader/core/parsers/esjzone/__init__.py +0 -10
- novel_downloader/core/parsers/linovelib/__init__.py +0 -10
- novel_downloader/core/parsers/qianbi/__init__.py +0 -10
- novel_downloader/core/parsers/sfacg/__init__.py +0 -10
- novel_downloader/core/parsers/yamibo/__init__.py +0 -10
- novel_downloader/core/parsers/yamibo/main_parser.py +0 -194
- novel_downloader/models/browser.py +0 -21
- novel_downloader/models/chapter.py +0 -25
- novel_downloader/models/site_rules.py +0 -99
- novel_downloader/models/tasks.py +0 -33
- novel_downloader/models/types.py +0 -15
- novel_downloader/resources/css_styles/volume-intro.css +0 -56
- novel_downloader/resources/json/replace_word_map.json +0 -4
- novel_downloader/resources/text/blacklist.txt +0 -22
- novel_downloader/tui/__init__.py +0 -7
- novel_downloader/tui/app.py +0 -32
- novel_downloader/tui/main.py +0 -17
- novel_downloader/tui/screens/__init__.py +0 -14
- novel_downloader/tui/screens/home.py +0 -198
- novel_downloader/tui/screens/login.py +0 -74
- novel_downloader/tui/styles/home_layout.tcss +0 -79
- novel_downloader/tui/widgets/richlog_handler.py +0 -24
- novel_downloader/utils/cache.py +0 -24
- novel_downloader/utils/fontocr/__init__.py +0 -22
- novel_downloader/utils/fontocr/model_loader.py +0 -69
- novel_downloader/utils/fontocr/ocr_v1.py +0 -303
- novel_downloader/utils/fontocr/ocr_v2.py +0 -752
- novel_downloader/utils/hash_store.py +0 -279
- novel_downloader/utils/hash_utils.py +0 -103
- novel_downloader/utils/text_utils/chapter_formatting.py +0 -46
- novel_downloader/utils/text_utils/font_mapping.py +0 -28
- novel_downloader/utils/text_utils/text_cleaning.py +0 -107
- novel_downloader-1.4.5.dist-info/METADATA +0 -196
- novel_downloader-1.4.5.dist-info/RECORD +0 -165
- {novel_downloader-1.4.5.dist-info → novel_downloader-2.0.0.dist-info}/WHEEL +0 -0
- {novel_downloader-1.4.5.dist-info → novel_downloader-2.0.0.dist-info}/licenses/LICENSE +0 -0
- {novel_downloader-1.4.5.dist-info → novel_downloader-2.0.0.dist-info}/top_level.txt +0 -0
@@ -5,27 +5,11 @@ novel_downloader.models.config
|
|
5
5
|
|
6
6
|
Defines structured configuration models using dataclasses for each
|
7
7
|
major component in the novel_downloader pipeline.
|
8
|
-
|
9
|
-
Each config section corresponds to a specific stage of the pipeline:
|
10
|
-
- RequesterConfig: network settings for requests and DrissionPage
|
11
|
-
- DownloaderConfig: chapter download behavior and local raw data paths
|
12
|
-
- ParserConfig: font decoding, cache handling, and debug options
|
13
|
-
- SaverConfig: output formatting, export formats, and filename templates
|
14
|
-
|
15
|
-
These models are used to map loaded YAML or JSON config data into
|
16
|
-
strongly typed Python objects for safer and cleaner access.
|
17
8
|
"""
|
18
9
|
|
19
|
-
from dataclasses import dataclass
|
10
|
+
from dataclasses import dataclass, field
|
20
11
|
from typing import NotRequired, TypedDict
|
21
12
|
|
22
|
-
from .types import (
|
23
|
-
BrowserType,
|
24
|
-
ModeType,
|
25
|
-
SplitMode,
|
26
|
-
StorageBackend,
|
27
|
-
)
|
28
|
-
|
29
13
|
|
30
14
|
@dataclass
|
31
15
|
class FetcherConfig:
|
@@ -33,16 +17,12 @@ class FetcherConfig:
|
|
33
17
|
retry_times: int = 3
|
34
18
|
backoff_factor: float = 2.0
|
35
19
|
timeout: float = 30.0
|
36
|
-
headless: bool = False
|
37
|
-
disable_images: bool = False
|
38
|
-
mode: ModeType = "session"
|
39
20
|
max_connections: int = 10
|
40
|
-
max_rps: float
|
41
|
-
proxy: str | None = None
|
21
|
+
max_rps: float = 1000.0
|
42
22
|
user_agent: str | None = None
|
43
23
|
headers: dict[str, str] | None = None
|
44
|
-
browser_type: BrowserType = "chromium"
|
45
24
|
verify_ssl: bool = True
|
25
|
+
locale_style: str = "simplified"
|
46
26
|
|
47
27
|
|
48
28
|
@dataclass
|
@@ -52,17 +32,11 @@ class DownloaderConfig:
|
|
52
32
|
backoff_factor: float = 2.0
|
53
33
|
raw_data_dir: str = "./raw_data"
|
54
34
|
cache_dir: str = "./novel_cache"
|
55
|
-
|
56
|
-
parser_workers: int = 4
|
35
|
+
workers: int = 4
|
57
36
|
skip_existing: bool = True
|
58
37
|
login_required: bool = False
|
59
38
|
save_html: bool = False
|
60
|
-
mode: ModeType = "session"
|
61
|
-
storage_backend: StorageBackend = "json"
|
62
39
|
storage_batch_size: int = 1
|
63
|
-
username: str = ""
|
64
|
-
password: str = ""
|
65
|
-
cookies: str = ""
|
66
40
|
|
67
41
|
|
68
42
|
@dataclass
|
@@ -70,17 +44,17 @@ class ParserConfig:
|
|
70
44
|
cache_dir: str = "./novel_cache"
|
71
45
|
use_truncation: bool = True
|
72
46
|
decode_font: bool = False
|
73
|
-
use_freq: bool = False
|
74
|
-
use_ocr: bool = True
|
75
|
-
use_vec: bool = False
|
76
|
-
ocr_version: str = "v1.0"
|
77
47
|
batch_size: int = 32
|
78
|
-
gpu_mem: int = 500
|
79
|
-
gpu_id: int | None = None
|
80
|
-
ocr_weight: float = 0.6
|
81
|
-
vec_weight: float = 0.4
|
82
48
|
save_font_debug: bool = False
|
83
|
-
|
49
|
+
|
50
|
+
|
51
|
+
@dataclass
|
52
|
+
class TextCleanerConfig:
|
53
|
+
remove_invisible: bool = True
|
54
|
+
title_remove_patterns: list[str] = field(default_factory=list)
|
55
|
+
title_replacements: dict[str, str] = field(default_factory=dict)
|
56
|
+
content_remove_patterns: list[str] = field(default_factory=list)
|
57
|
+
content_replacements: dict[str, str] = field(default_factory=dict)
|
84
58
|
|
85
59
|
|
86
60
|
@dataclass
|
@@ -88,7 +62,6 @@ class ExporterConfig:
|
|
88
62
|
cache_dir: str = "./novel_cache"
|
89
63
|
raw_data_dir: str = "./raw_data"
|
90
64
|
output_dir: str = "./downloads"
|
91
|
-
storage_backend: StorageBackend = "json"
|
92
65
|
clean_text: bool = True
|
93
66
|
make_txt: bool = True
|
94
67
|
make_epub: bool = False
|
@@ -97,9 +70,9 @@ class ExporterConfig:
|
|
97
70
|
append_timestamp: bool = True
|
98
71
|
filename_template: str = "{title}_{author}"
|
99
72
|
include_cover: bool = True
|
100
|
-
|
101
|
-
|
102
|
-
|
73
|
+
include_picture: bool = True
|
74
|
+
split_mode: str = "book"
|
75
|
+
cleaner_cfg: TextCleanerConfig = field(default_factory=TextCleanerConfig)
|
103
76
|
|
104
77
|
|
105
78
|
class BookConfig(TypedDict):
|
novel_downloader/models/login.py
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
novel_downloader.models.search
|
4
|
+
------------------------------
|
5
|
+
|
6
|
+
"""
|
7
|
+
|
8
|
+
from typing import TypedDict
|
9
|
+
|
10
|
+
|
11
|
+
class SearchResult(TypedDict, total=True):
|
12
|
+
site: str
|
13
|
+
book_id: str
|
14
|
+
book_url: str
|
15
|
+
cover_url: str
|
16
|
+
title: str
|
17
|
+
author: str
|
18
|
+
latest_chapter: str
|
19
|
+
update_date: str
|
20
|
+
word_count: str
|
21
|
+
priority: int
|
@@ -1,31 +1,18 @@
|
|
1
|
-
#
|
2
|
-
[
|
1
|
+
# 全局通用设置
|
2
|
+
[general]
|
3
3
|
retry_times = 3 # 请求失败重试次数
|
4
4
|
backoff_factor = 2.0
|
5
5
|
timeout = 30.0 # 页面加载超时时间 (秒)
|
6
6
|
max_connections = 10 # 并发连接的最大数
|
7
|
-
max_rps = 1.0 # 最大请求速率 (requests per second),
|
8
|
-
# proxy = "http://127.0.0.1:1080" # 如需使用代理, 填写完整的代理地址
|
9
|
-
# user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
|
10
|
-
# headers = {}
|
11
|
-
browser_type = "chromium"
|
12
|
-
verify_ssl = true
|
13
|
-
|
14
|
-
# 浏览器设置
|
15
|
-
headless = false # 是否以无头模式启动浏览器
|
16
|
-
disable_images = false # 是否禁用图片加载 (加速)
|
17
|
-
|
18
|
-
# 全局通用设置
|
19
|
-
[general]
|
7
|
+
max_rps = 1.0 # 最大请求速率 (requests per second), 如不设置则请设置一个较大的数或负数
|
20
8
|
request_interval = 2.0 # 同一本书各章节请求间隔 (秒)
|
21
9
|
raw_data_dir = "./raw_data" # 原始章节 JSON/DB 存放目录
|
22
10
|
output_dir = "./downloads" # 最终输出文件存放目录
|
23
11
|
cache_dir = "./novel_cache" # 本地缓存目录 (字体 / 图片等)
|
24
|
-
|
25
|
-
parser_workers = 2 # 并发解析线程数
|
12
|
+
workers = 2 # 工作协程数
|
26
13
|
skip_existing = true # 是否跳过已存在章节
|
27
|
-
|
28
|
-
|
14
|
+
storage_batch_size = 1 # SQLite 批量提交的章节数量
|
15
|
+
locale_style = "simplified" # simplified / traditional
|
29
16
|
|
30
17
|
[general.debug]
|
31
18
|
save_html = false # 是否将抓取到的原始 HTML 保留到磁盘
|
@@ -33,16 +20,8 @@ log_level = "INFO" # 日志级别: DEBUG, INFO, WARNING, ERROR
|
|
33
20
|
|
34
21
|
[general.font_ocr]
|
35
22
|
decode_font = false # 是否尝试本地解码混淆字体
|
36
|
-
use_freq = false # 是否使用频率分析
|
37
|
-
ocr_version = "v2.0" # "v1.0" / "v2.0"
|
38
|
-
use_ocr = true # 是否使用 OCR 辅助识别文本
|
39
|
-
use_vec = false # 是否使用 Vector 辅助识别文本
|
40
|
-
save_font_debug = false # 是否保存字体解码调试数据
|
41
23
|
batch_size = 32
|
42
|
-
|
43
|
-
# gpu_id = # 使用哪个 GPU
|
44
|
-
ocr_weight = 0.5
|
45
|
-
vec_weight = 0.5
|
24
|
+
save_font_debug = false # 是否保存字体解码调试数据
|
46
25
|
|
47
26
|
# 各站点的特定配置
|
48
27
|
[sites.qidian] # 起点中文网
|
@@ -50,76 +29,33 @@ book_ids = [
|
|
50
29
|
"0000000000",
|
51
30
|
"0000000000"
|
52
31
|
]
|
53
|
-
mode = "session" # browser / session
|
54
32
|
login_required = true # 是否需要登录才能访问
|
55
33
|
use_truncation = true # 是否基于章节长度截断以避免重复内容
|
56
34
|
|
57
|
-
[sites.biquge] # 笔趣阁
|
58
|
-
book_ids = [
|
59
|
-
"0000000000",
|
60
|
-
"0000000000"
|
61
|
-
]
|
62
|
-
mode = "session" # browser / session
|
63
|
-
login_required = false
|
64
|
-
|
65
|
-
[sites.qianbi] # 铅笔小说
|
66
|
-
book_ids = [
|
67
|
-
"0000000000",
|
68
|
-
"0000000000"
|
69
|
-
]
|
70
|
-
mode = "session" # browser / session
|
71
|
-
login_required = false
|
72
|
-
|
73
|
-
[sites.sfacg] # SF轻小说
|
74
|
-
book_ids = [
|
75
|
-
"0000000000",
|
76
|
-
"0000000000"
|
77
|
-
]
|
78
|
-
mode = "session" # browser / session
|
79
|
-
login_required = false
|
80
|
-
|
81
35
|
[sites.esjzone] # ESJ Zone
|
82
36
|
book_ids = [
|
83
37
|
"0000000000",
|
84
38
|
"0000000000"
|
85
39
|
]
|
86
|
-
mode = "session" # browser / session
|
87
40
|
login_required = true
|
88
41
|
# username = "youremail@domain.com" # 登录邮箱
|
89
42
|
# password = "yourpassword" # 登录密码
|
90
43
|
|
91
|
-
[sites.yamibo] # 百合会
|
92
|
-
book_ids = [
|
93
|
-
"0000000000",
|
94
|
-
"0000000000"
|
95
|
-
]
|
96
|
-
mode = "session" # browser / session
|
97
|
-
login_required = false
|
98
|
-
# username = "yourusername" # 登录账户
|
99
|
-
# password = "yourpassword" # 登录密码
|
100
|
-
|
101
44
|
[sites.linovelib] # 哔哩轻小说
|
102
45
|
book_ids = [
|
103
46
|
"0000000000",
|
104
47
|
"0000000000"
|
105
48
|
]
|
106
|
-
mode = "session"
|
107
49
|
split_mode = "book" # 导出方式: book / volume
|
108
50
|
login_required = false
|
109
51
|
|
110
52
|
[sites.common]
|
111
|
-
mode = "session" # browser / session
|
112
53
|
login_required = false
|
113
54
|
|
114
55
|
# 输出文件格式及相关选项
|
115
|
-
[output]
|
116
|
-
clean_text = true # 是否对章节文本做清理
|
117
|
-
|
118
56
|
[output.formats]
|
119
57
|
make_txt = true # 是否生成完整 TXT 文件
|
120
|
-
make_epub =
|
121
|
-
make_md = false # 是否生成 Markdown (未实现)
|
122
|
-
make_pdf = false # 可能支持 PDF 输出 (未实现)
|
58
|
+
make_epub = true # 是否生成 EPUB
|
123
59
|
|
124
60
|
[output.naming]
|
125
61
|
append_timestamp = false # 在文件名中追加时间戳
|
@@ -127,5 +63,34 @@ filename_template = "{title}_{author}" # 文件命名规则
|
|
127
63
|
|
128
64
|
[output.epub]
|
129
65
|
include_cover = true # 是否在 EPUB 中包含封面
|
130
|
-
|
131
|
-
|
66
|
+
include_picture = true # 是否下载章节图片 (体积较大)
|
67
|
+
|
68
|
+
[cleaner]
|
69
|
+
clean_text = false # 是否对章节文本做清理
|
70
|
+
remove_invisible = true
|
71
|
+
|
72
|
+
[cleaner.title]
|
73
|
+
remove_patterns = [
|
74
|
+
'【[^】]*?】',
|
75
|
+
'[((][^()()]*?求票[^()()]*?[))]',
|
76
|
+
]
|
77
|
+
|
78
|
+
[cleaner.title.replace]
|
79
|
+
':' = ':'
|
80
|
+
|
81
|
+
[cleaner.title.external]
|
82
|
+
enabled = false
|
83
|
+
remove_patterns = "path/to/title-remove.json"
|
84
|
+
replace = "path/to/title-replace.json"
|
85
|
+
|
86
|
+
[cleaner.content]
|
87
|
+
remove_patterns = []
|
88
|
+
|
89
|
+
[cleaner.content.replace]
|
90
|
+
'li子' = '例子'
|
91
|
+
'pinbi词' = '屏蔽词'
|
92
|
+
|
93
|
+
[cleaner.content.external]
|
94
|
+
enabled = false
|
95
|
+
remove_patterns = "path/to/content-remove.json"
|
96
|
+
replace = "path/to/content-replace.json"
|
@@ -0,0 +1,83 @@
|
|
1
|
+
body {
|
2
|
+
font-family: serif;
|
3
|
+
line-height: 1.5;
|
4
|
+
height: 95%;
|
5
|
+
margin: 2em;
|
6
|
+
}
|
7
|
+
|
8
|
+
h1 {
|
9
|
+
font-size: 2em;
|
10
|
+
text-align: center;
|
11
|
+
margin-bottom: 1em;
|
12
|
+
}
|
13
|
+
|
14
|
+
p.new-page-after {
|
15
|
+
page-break-after: always;
|
16
|
+
margin: 0;
|
17
|
+
padding: 0;
|
18
|
+
}
|
19
|
+
|
20
|
+
.intro-info {
|
21
|
+
list-style: none;
|
22
|
+
padding: 0;
|
23
|
+
margin: 0 0 2em;
|
24
|
+
}
|
25
|
+
.intro-info li {
|
26
|
+
margin: 0.5em 0;
|
27
|
+
font-size: 1.1em;
|
28
|
+
}
|
29
|
+
|
30
|
+
.intro-summary {
|
31
|
+
margin-top: 1em;
|
32
|
+
font-size: 1em;
|
33
|
+
}
|
34
|
+
|
35
|
+
.vol-header {
|
36
|
+
display: flex;
|
37
|
+
flex-direction: column;
|
38
|
+
justify-content: center;
|
39
|
+
align-items: center;
|
40
|
+
margin: 0;
|
41
|
+
}
|
42
|
+
|
43
|
+
.vol-border {
|
44
|
+
width: 100%;
|
45
|
+
text-align: center;
|
46
|
+
margin: 0 auto 0 auto;
|
47
|
+
text-indent: 0em;
|
48
|
+
}
|
49
|
+
.vol-border.flip {
|
50
|
+
transform: rotate(180deg);
|
51
|
+
-ms-transform: rotate(180deg);
|
52
|
+
-moz-transform: rotate(180deg);
|
53
|
+
-webkit-transform: rotate(180deg);
|
54
|
+
-o-transform: rotate(180deg);
|
55
|
+
}
|
56
|
+
|
57
|
+
.vol-title-main,
|
58
|
+
.vol-title-sub {
|
59
|
+
font-weight: bold;
|
60
|
+
text-align: center;
|
61
|
+
text-indent: 0em;
|
62
|
+
color: #6e471c;
|
63
|
+
margin: 0.25em 0;
|
64
|
+
display: block;
|
65
|
+
color: #6e471c;
|
66
|
+
text-shadow: 1px 1px 2px rgba(255,255,255,0.8);
|
67
|
+
}
|
68
|
+
.vol-title-main {
|
69
|
+
font-size: 1.25rem;
|
70
|
+
}
|
71
|
+
.vol-title-sub {
|
72
|
+
font-size: 1rem;
|
73
|
+
}
|
74
|
+
|
75
|
+
.volume-intro-text {
|
76
|
+
margin: 1em 0;
|
77
|
+
padding: 0 1em;
|
78
|
+
text-align: justify;
|
79
|
+
}
|
80
|
+
.volume-intro-text p {
|
81
|
+
margin: 0.5em 0;
|
82
|
+
line-height: 1.6;
|
83
|
+
}
|
@@ -1,104 +1,45 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
body {
|
2
|
+
font-family: serif;
|
3
|
+
height: 95%;
|
4
|
+
line-height: 1.6;
|
5
|
+
margin: 1em;
|
4
6
|
}
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
margin:0 0 1.5em;
|
11
|
-
}
|
12
|
-
.article .images {
|
13
|
-
margin:1.0em 0;
|
14
|
-
border:1px solid #000
|
15
|
-
}
|
16
|
-
|
17
|
-
.new-page-after {
|
18
|
-
page-break-after:always;
|
19
|
-
}
|
20
|
-
|
21
|
-
.cover {
|
22
|
-
width:100%;
|
23
|
-
padding:0px;
|
24
|
-
}
|
25
|
-
.center {
|
26
|
-
text-align: center;
|
27
|
-
margin-left: 0%;
|
28
|
-
margin-right: 0%;
|
29
|
-
}
|
30
|
-
.left {
|
31
|
-
text-align: center;
|
32
|
-
margin-left: 0%;
|
33
|
-
margin-right: 0%;
|
34
|
-
}
|
35
|
-
.right {
|
36
|
-
text-align: right;
|
37
|
-
margin-left: 0%;
|
38
|
-
margin-right: 0%;
|
8
|
+
h2 {
|
9
|
+
font-size: 1.5em;
|
10
|
+
margin: 1.5em 0 0.75em;
|
11
|
+
text-align: center;
|
39
12
|
}
|
40
13
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
border-width: 1px 0 0 0;
|
45
|
-
margin-top: 0.5em;
|
46
|
-
margin-bottom: 0.5em;
|
47
|
-
}
|
48
|
-
|
49
|
-
h1 {
|
50
|
-
text-indent: 0;
|
51
|
-
duokan-text-indent: 0;
|
52
|
-
line-height: 110%;
|
53
|
-
text-align: center;
|
54
|
-
font-size: 1.2em;
|
55
|
-
margin-top: 0.4em;
|
56
|
-
margin-bottom: 0.4em;
|
57
|
-
}
|
58
|
-
|
59
|
-
h2, h3, h4, h5, h6 {
|
60
|
-
text-indent: 0;
|
61
|
-
duokan-text-indent: 0;
|
62
|
-
line-height: 110%;
|
63
|
-
font-size: 1.1em;
|
64
|
-
margin-top: 0.4em;
|
65
|
-
margin-bottom: 0.4em;
|
14
|
+
p {
|
15
|
+
text-indent: 2em;
|
16
|
+
margin: 0.5em 0;
|
66
17
|
}
|
67
18
|
|
68
|
-
p {
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
line-height: 100%;
|
73
|
-
margin-top: 0.4em;
|
74
|
-
margin-bottom: 0.4em;
|
19
|
+
p.new-page-after {
|
20
|
+
margin: 0;
|
21
|
+
padding: 0;
|
22
|
+
page-break-after: always;
|
75
23
|
}
|
76
24
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
line-height: 130%;
|
25
|
+
.duokan-image-single {
|
26
|
+
text-align: center;
|
27
|
+
margin: 1em 0;
|
81
28
|
}
|
82
29
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
font-size: 1em;
|
30
|
+
.duokan-image-single img {
|
31
|
+
max-width: 100%;
|
32
|
+
height: auto;
|
33
|
+
display: inline-block;
|
88
34
|
}
|
89
35
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
margin-left: 0;
|
95
|
-
list-style-type: none;
|
36
|
+
hr {
|
37
|
+
border: none;
|
38
|
+
border-top: 1px solid #ccc;
|
39
|
+
margin: 1.5em 0;
|
96
40
|
}
|
97
41
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
margin-bottom: 0.4em;
|
102
|
-
margin-left: 0;
|
103
|
-
list-style-type: none;
|
42
|
+
h3 {
|
43
|
+
font-size: 1.2em;
|
44
|
+
margin: 1em 0 0.5em;
|
104
45
|
}
|