一个功能强大的Web小说下载工具,支持从网站批量下载小说章节,并提供多种输出格式。
🔄 最新更新:项目已重构为模块化架构,提高了代码的可读性和可维护性。所有功能保持不变,使用方式完全兼容。
- 智能章节解析:使用XPath表达式精确提取章节链接和内容
- 并发下载:支持多线程并发下载,提高效率
- 分页支持:
- 章节内分页:处理跨多页的章节内容
- 章节列表分页:支持多页章节列表的自动翻页
- 内容处理:
- 正则表达式过滤
- 字符串替换(支持图片标签替换为文字)
- 内容清理和格式化
- 多种输出格式:
- TXT:纯文本格式
- EPUB:标准电子书格式,支持目录导航
- 元数据管理:自动保存和加载章节信息
- 章节组织:按元数据哈希组织章节文件到
chapters_<hash>/目录 - 断点续传:跳过已下载的章节
- Cloudflare保护处理:自动处理反爬虫保护
- 配置文件系统:支持JSON配置文件,一键执行完整工作流程
- 浏览器控制:支持无头模式和有头模式切换
- 智能跳过:自动跳过已存在的元数据文件,支持断点续传
- 反检测机制:内置反爬虫检测和Cloudflare保护处理
- 错误处理:完善的错误检测和用户友好的错误信息
项目提供了预构建的可执行文件,无需安装Python环境即可使用:
- 文件:
dist/web-novel-downloader.exe - 大小: 约15MB
- 要求: Windows 10/11
- 使用: 双击运行或命令行调用
- 文件:
dist/web-novel-downloader.app - 大小: 约15MB
- 要求: macOS 10.14+
- 使用: 双击运行或命令行调用
# Windows(默认后台运行)
./web-novel-downloader.exe parse --menu-url "https://example.com/novel" --chapter-xpath "//a[@class='chapter-link']" --content-xpath "//div[@class='content']"
# macOS(默认后台运行)
./web-novel-downloader.app/Contents/MacOS/web-novel-downloader parse --menu-url "https://example.com/novel" --chapter-xpath "//a[@class='chapter-link']" --content-xpath "//div[@class='content']"
# 显示浏览器窗口(用于调试)
./web-novel-downloader.exe parse --menu-url "https://example.com/novel" --chapter-xpath "//a[@class='chapter-link']" --content-xpath "//div[@class='content']" --no-headless# Windows(默认后台运行)
./web-novel-downloader.exe download --metadata-file chapters/metadata/chapters_<hash>.json --concurrency 5
# macOS(默认后台运行)
./web-novel-downloader.app/Contents/MacOS/web-novel-downloader download --metadata-file chapters/metadata/chapters_<hash>.json --concurrency 5
# 显示浏览器窗口(用于调试或手动处理验证)
./web-novel-downloader.exe download --metadata-file chapters/metadata/chapters_<hash>.json --concurrency 5 --no-headless# Windows
./web-novel-downloader.exe replace --metadata-file chapters/metadata/chapters_<hash>.json --string-replacements "[['<p>',''],['</p>',''],['<div>',''],['</div>','']]"
# macOS
./web-novel-downloader.app/Contents/MacOS/web-novel-downloader replace --metadata-file chapters/metadata/chapters_<hash>.json --string-replacements "[['<p>',''],['</p>',''],['<div>',''],['</div>','']]"# Windows
./web-novel-downloader.exe merge --metadata-file chapters/metadata/chapters_<hash>.json --format txt --output "my_novel.txt" --title "小说标题"
# macOS
./web-novel-downloader.app/Contents/MacOS/web-novel-downloader merge --metadata-file chapters/metadata/chapters_<hash>.json --format txt --output "my_novel.txt" --title "小说标题"# Windows
./web-novel-downloader.exe merge --metadata-file chapters/metadata/chapters_<hash>.json --format epub --output "my_novel.epub" --title "小说标题" --author "作者名"
# macOS
./web-novel-downloader.app/Contents/MacOS/web-novel-downloader merge --metadata-file chapters/metadata/chapters_<hash>.json --format epub --output "my_novel.epub" --title "小说标题" --author "作者名"使用配置文件可以一次性完成所有步骤,无需手动执行每个命令。
在项目根目录创建 configs/ 文件夹,然后创建JSON配置文件:
{
"version": "1.0",
"task_name": "我的小说下载任务",
"description": "从example.com下载小说的配置",
"browser": {
"chrome_path": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"headless": true,
"proxy": null
},
"novel": {
"menu_url": "https://www.example.com/book/123456",
"title": "我的最爱小说",
"author": "作者名称",
"output_filename": "my_favorite_novel"
},
"parsing": {
"hash": "my_novel_123",
"chapter_xpath": "(//div[@class='bd'])[2]//ul[@class='list']//li/a",
"content_xpath": "//div[@class='page-content']",
"chapter_pagination_xpath": null,
"chapter_list_pagination_xpath": "//a[contains(text(),'下一页')]",
"content_regex": null
},
"downloading": {
"concurrency": 3,
"content_regex": null
},
"processing": {
"string_replacements": [
["<p>", ""],
["</p>", ""],
["<div>", ""],
["</div>", ""]
],
"regex_replacements": [
["<img[^>]*>", "[图片]"],
["\\s+", " "]
],
"case_sensitive": false,
"backup_enabled": false,
"file_pattern": "*.html"
},
"merging": {
"format": "epub",
"reverse_order": false,
"output_directory": "~/Downloads/Novels"
}
}./web-novel-downloader.exe config validate configs/my_novel.json./web-novel-downloader.exe task --config configs/my_novel.json这个命令会自动执行以下步骤:
- 解析章节列表(如果元数据文件已存在则跳过)
- 下载所有章节内容
- 处理内容(字符串替换等)
- 合并为最终文件
系统会自动检测已存在的元数据文件:
- 如果元数据文件存在且URL匹配,自动跳过解析步骤
- 如果元数据文件存在但URL不匹配,会重新解析
- 支持断点续传,避免重复下载已完成的章节
内置多种反爬虫检测机制:
- 自动检测Cloudflare保护页面
- 智能处理404错误页面
- 反自动化检测(禁用自动化标识)
- 自定义User-Agent和浏览器参数
解析网站上的章节列表,提取章节链接和标题。
必需参数:
--menu-url:小说目录页URL--chapter-xpath:章节链接的XPath表达式--content-xpath:章节内容的XPath表达式
可选参数:
--chapter-pagination-xpath:章节内分页的XPath表达式--chapter-list-pagination-xpath:章节列表分页的XPath表达式--content-regex:内容过滤的正则表达式--string-replacements:字符串替换规则(JSON格式)--proxy:代理服务器地址--headless:无头模式运行浏览器(默认:True)--no-headless:显示浏览器窗口
示例:
./web-novel-downloader.exe parse \
--menu-url "https://www.example.com/book/123456" \
--chapter-xpath "(//div[@class='bd'])[2]//ul[@class='list']//li/a" \
--content-xpath "//div[@class='page-content']" \
--chapter-list-pagination-xpath "//a[contains(text(),'下一页')]" \
--string-replacements "[['<p>',''],['</p>',''],['<div>',''],['</div>','']]"使用已保存的元数据下载章节内容。
必需参数:
--metadata-file:指定要使用的chapters_<hash>.json元数据文件路径(支持相对路径)
可选参数:
--concurrency:并发下载数量(默认3)--proxy:代理服务器地址--content-regex:内容过滤的正则表达式(覆盖元数据中的设置)--headless:无头模式运行浏览器(默认:True)--no-headless:显示浏览器窗口
示例:
# 使用元数据文件下载
./web-novel-downloader.exe download --metadata-file chapters/metadata/chapters_879584cc.json
# 指定并发数量
./web-novel-downloader.exe download --metadata-file chapters/metadata/chapters_879584cc.json --concurrency 5
# 使用代理下载
./web-novel-downloader.exe download --metadata-file chapters/metadata/chapters_879584cc.json --proxy 127.0.0.1:10808将下载的章节合并为单个文件。
必需参数:
--metadata-file:指定要使用的chapters_<hash>.json元数据文件路径(支持相对路径)--output:输出文件名
可选参数:
--format:输出格式(txt/epub,默认txt)--title:小说标题--author:作者名称(EPUB格式需要)
示例:
# 生成TXT文件
./web-novel-downloader.exe merge --metadata-file chapters/metadata/chapters_879584cc.json --format txt --output "my_novel.txt" --title "我的小说"
# 生成EPUB文件
./web-novel-downloader.exe merge --metadata-file chapters/metadata/chapters_879584cc.json --format epub --output "my_novel.epub" --title "我的小说" --author "作者名"对已下载的章节文件进行字符串替换。
必需参数:
--metadata-file:指定要使用的chapters_<hash>.json元数据文件路径(支持相对路径)--string-replacements:替换规则(JSON格式)
💡 JSON格式说明:支持两种格式:
- 单引号格式:
[['old1','new1'],['old2','new2']]- 双引号格式:
[["old1","new1"],["old2","new2"]]
可选参数:
--regex-replacements:正则表达式替换规则--case-sensitive:是否区分大小写(默认False)--backup:是否创建备份文件--dry-run:预览模式,不实际修改文件--pattern:文件匹配模式(默认*.html)
示例:
# 基本字符串替换(单引号格式)
./web-novel-downloader.exe replace --metadata-file chapters/metadata/chapters_879584cc.json --string-replacements "[['<p>',''],['</p>','']]"
# 基本字符串替换(双引号格式)
./web-novel-downloader.exe replace --metadata-file chapters/metadata/chapters_879584cc.json --string-replacements "[[\"<p>\",\"\"],[\"</p>\",\"\"],[\"<br>\",\"\\n\"]]"
# 预览模式
./web-novel-downloader.exe replace --metadata-file chapters/metadata/chapters_879584cc.json --string-replacements "[['old','new']]" --dry-run
# 正则表达式替换
./web-novel-downloader.exe replace --metadata-file chapters/metadata/chapters_879584cc.json --regex-replacements "[['<img[^>]*>','[IMAGE]']]"
# 创建备份
./web-novel-downloader.exe replace --metadata-file chapters/metadata/chapters_879584cc.json --string-replacements "[['old','new']]" --backup章节内分页:处理跨多页的章节内容
./web-novel-downloader.exe parse \
--menu-url "https://example.com/novel" \
--chapter-xpath "//a[@class='chapter']" \
--content-xpath "//div[@class='content']" \
--chapter-pagination-xpath "//a[contains(text(),'下一页')]"章节列表分页:处理多页的章节列表
./web-novel-downloader.exe parse \
--menu-url "https://example.com/novel" \
--chapter-xpath "//a[@class='chapter']" \
--content-xpath "//div[@class='content']" \
--chapter-list-pagination-xpath "//a[contains(text(),'下一页')]"使用正则表达式过滤内容:
./web-novel-downloader.exe parse \
--menu-url "https://example.com/novel" \
--chapter-xpath "//a[@class='chapter']" \
--content-xpath "//div[@class='content']" \
--content-regex "第.*?章.*?$"支持复杂的字符串替换规则:
# 清理HTML标签
./web-novel-downloader.exe replace \
--string-replacements "[['<p>',''],['</p>',''],['<div>',''],['</div>','']]"-
Cloudflare保护:
- 程序会自动处理Cloudflare保护
- 如果遇到问题,请等待几分钟后重试
-
XPath表达式错误:
- 使用浏览器开发者工具检查元素结构
- 确保XPath表达式正确匹配目标元素
-
内容提取失败:
- 检查content-xpath是否正确
- 尝试更简单的XPath表达式
-
EPUB文件问题:
- 确保使用支持EPUB的阅读器
- 检查文件是否完整下载
- 使用dry-run模式:
./web-novel-downloader.exe replace --string-replacements "[['old','new']]" --dry-run- 检查元数据:
ls chapters/metadata/
cat chapters/metadata/*.json- 查看章节文件:
ls chapters/
head -20 chapters/*.html使用本工具进行开发需要具备以下基础知识:
- XPath基础:能够编写XPath表达式来定位HTML元素
- HTML基础:理解HTML结构,能够识别网页元素
- 浏览器开发者工具:会使用F12开发者工具检查元素结构
- Python基础:具备基本的Python命令行使用能力
💡 提示:如果不熟悉XPath,建议先学习XPath语法。可以使用浏览器开发者工具的Console标签测试XPath表达式:
$x("your-xpath-here")
pip install -e .# 安装开发依赖
pip install -e ".[dev]"
# 或使用构建脚本
python scripts/build/build.py --help- 解析章节列表:
python scripts/book_downloader.py parse --menu-url "https://example.com/novel" --chapter-xpath "//a[@class='chapter-link']" --content-xpath "//div[@class='content']"- 下载章节:
python scripts/book_downloader.py download --metadata-file chapters/metadata/chapters_879584cc.json --concurrency 5- 章节内容字符串替换(可选):
python scripts/book_downloader.py replace --metadata-file chapters/metadata/chapters_879584cc.json --string-replacements "[['<p>',''],['</p>',''],['<div>',''],['</div>','']]"- 合并为TXT文件:
python scripts/book_downloader.py merge --metadata-file chapters/metadata/chapters_879584cc.json --format txt --output "my_novel.txt" --title "小说标题"- 合并为EPUB文件:
python scripts/book_downloader.py merge --metadata-file chapters/metadata/chapters_879584cc.json --format epub --output "my_novel.epub" --title "小说标题" --author "作者名"- 安装包:
pip install -e .- 使用命令行工具:
web-novel-downloader parse --menu-url "https://example.com/novel" --chapter-xpath "//a[@class='chapter-link']" --content-xpath "//div[@class='content']"
web-novel-downloader download --metadata-file chapters/metadata/chapters_879584cc.json --concurrency 5
web-novel-downloader merge --metadata-file chapters/metadata/chapters_879584cc.json --format epub --output "my_novel.epub" --title "小说标题" --author "作者名"from book_downloader import NovelDownloader
# 创建下载器实例
downloader = NovelDownloader(
chapter_xpath="//a[@class='chapter-link']",
content_xpath="//div[@class='content']",
concurrency=5
)
# 下载小说
import asyncio
asyncio.run(downloader.download_novel("https://example.com/novel"))pytestblack src/ tests/ scripts/mypy src/# 使用构建脚本(推荐)
python scripts/build/build.py --packages --version v0.0.1
# 或手动构建
python -m build# 使用构建脚本(推荐)
python scripts/build/build.py --exe windows --version v0.0.1
# 或手动构建
pyinstaller build_win.spec --clean
# 构建所有内容
python scripts/build/build.py --all# 从构建的包安装
pip install dist/book_downloader-1.0.0-py3-none-any.whl
# 或从源码安装
pip install .- 模块化架构:代码拆分为多个模块,提高可读性和可维护性
- 异步处理:使用asyncio实现高效的异步下载
- 浏览器自动化:基于pydoll的浏览器自动化,支持JavaScript渲染
- XPath解析:使用lxml进行精确的HTML解析
- EPUB标准:完全符合EPUB 2.0标准,支持各种电子书阅读器
- 错误处理:完善的错误处理和恢复机制
- 进度显示:详细的下载进度和状态显示
- 元数据管理:智能的章节信息存储和检索
- 跨平台构建:支持Windows和macOS可执行文件构建
- 智能构建系统:自动回退机制,确保构建成功
pydoll-python:浏览器自动化lxml:HTML/XML解析asyncio:异步编程支持(Python内置)
项目采用模块化设计,将原来的单一文件拆分为多个功能模块:
config.py:配置和常量管理utils.py:通用工具函数metadata.py:章节元数据管理epub_generator.py:EPUB文件生成core.py:核心下载功能(NovelDownloader类)cli.py:命令行接口和参数解析novel_downloader.py:主入口文件
这种设计提高了代码的可读性、可维护性和可扩展性。详细说明请参考 PROJECT_STRUCTURE.md。
book-downloader/
├── src/ # 源代码目录
│ └── book_downloader/ # 主包
│ ├── __init__.py # 包初始化文件
│ ├── config.py # 配置和常量
│ ├── utils.py # 工具函数
│ ├── metadata.py # 元数据管理
│ ├── epub_generator.py # EPUB生成模块
│ ├── core.py # 核心下载功能
│ ├── cli.py # 命令行接口
│ └── scraper.py # 基础爬虫模块
├── scripts/ # 可执行脚本
│ ├── book_downloader.py # 主入口脚本
│ └── scraper.py # 爬虫脚本
├── tests/ # 测试目录
│ ├── __init__.py
│ ├── conftest.py # 测试配置
│ ├── test_utils.py # 工具函数测试
│ └── test_config.py # 配置测试
├── spec/ # 项目规范文档
│ ├── develop-logs/ # 开发日志
│ └── development-progress.md
├── chapters/ # 章节文件目录
│ ├── metadata/ # 元数据存储
│ │ └── chapters_<hash>.json # 章节元数据文件
│ ├── chapters_<hash>/ # 按元数据哈希组织的章节目录
│ │ └── *.html # 下载的章节文件
│ └── chapters_<other_hash>/ # 其他小说的章节目录
├── temp/ # 临时文件目录
├── setup.py # 安装脚本
├── pyproject.toml # 现代Python项目配置
├── build_win.spec # Windows PyInstaller配置
├── build_macos.spec # macOS PyInstaller配置
├── README.md # 说明文档
└── docs/ # 文档目录
├── QUICK_START.md # 快速开始指南
├── USAGE_GUIDE.md # 使用指南
└── PROJECT_STRUCTURE.md # 项目结构说明
欢迎提交Issue和Pull Request来改进这个项目。
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'Add some amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 打开 Pull Request
如果您遇到问题或有建议,请:
本项目采用MIT许可证。
本项目仅供学习和交流使用,严禁用于商业用途。
- 学习目的:本项目仅用于技术学习和个人研究
- 禁止商用:严禁将本项目用于任何商业用途
- 遵守法律:使用者需遵守当地法律法规和网站使用条款
- 版权尊重:请尊重原网站和作者的版权,仅下载个人学习使用
- 风险自担:使用本工具产生的任何后果由使用者自行承担
- 本项目不承担因使用本工具而产生的任何法律责任
- 使用者应当遵守目标网站的robots.txt和使用条款
- 请合理使用,避免对目标网站造成过大负担
- 如涉及版权问题,请立即停止使用并删除相关内容
请在使用前仔细阅读并同意以上条款。