一个功能强大的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和使用条款
- 请合理使用,避免对目标网站造成过大负担
- 如涉及版权问题,请立即停止使用并删除相关内容
请在使用前仔细阅读并同意以上条款。