1. 项目背景与核心价值
最近在整理个人电子书库时,发现很多优质网络小说资源分散在不同平台,手动保存效率极低。于是决定用Python开发一个自动化工具,实现小说章节的批量抓取、格式转换与本地存储。这个项目完美结合了爬虫数据采集、多线程加速、文件格式转换和数据库存储四大核心模块,特别适合需要批量获取网络文学资源的阅读爱好者。
传统单线程爬虫下载200章小说可能需要半小时,而通过多线程优化后能缩短到5分钟以内。配合EPUB生成功能,可以直接在Kindle或手机阅读器上享受排版精美的电子书。下面将从技术选型到完整实现,详细拆解这个工具的每个关键环节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体工作流程
- 爬虫模块:通过requests获取网页内容,BeautifulSoup解析章节列表
- 多线程调度:采用threading模块实现并发下载
- 数据存储:SQLite持久化保存原始数据
- 格式转换:使用pandoc将文本转为EPUB
- 辅助功能:CSV导出实现数据交换
2.2 技术选型对比
| 技术点 | 方案选择 | 替代方案 | 选择理由 |
|---|---|---|---|
| HTML解析 | BeautifulSoup4 | PyQuery | 学习曲线平缓,文档丰富 |
| 多线程实现 | threading | multiprocessing | 适合IO密集型任务,资源消耗低 |
| 数据库 | SQLite3 | MySQL | 零配置,单文件便携 |
| EPUB生成 | pandoc | ebooklib | 支持样式模板,排版效果好 |
提示:选择pandoc而非直接使用EPUB库的原因是其支持CSS样式注入,可以生成更适合电子阅读器显示的版式
3. 核心模块实现
3.1 反爬虫策略突破
针对常见的反爬机制,我们采用三重防护:
python复制headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': 'https://www.example.com',
'Accept-Language': 'zh-CN,zh;q=0.9'
}
proxies = {
'http': 'http://localhost:8888',
'https': 'http://localhost:8888'
}
def make_request(url):
time.sleep(random.uniform(1, 3))
response = requests.get(url, headers=headers, proxies=proxies)
return response
关键技巧:
- 随机延迟1-3秒避免高频访问
- 轮换User-Agent模拟不同浏览器
- 通过本地代理监控请求(如Charles)
3.2 多线程调度优化
采用生产者-消费者模型实现高效并发:
python复制from queue import Queue
import threading
class DownloadScheduler:
def __init__(self, thread_num=5):
self.task_queue = Queue()
self.threads = []
self._init_threads(thread_num)
def _init_threads(self, thread_num):
for i in range(thread_num):
t = threading.Thread(target=self._worker)
t.daemon = True
t.start()
self.threads.append(t)
def _worker(self):
while True:
chapter_url, save_path = self.task_queue.get()
download_chapter(chapter_url, save_path)
self.task_queue.task_done()
参数调优建议:
- IO密集型任务:线程数 = CPU核心数 × 3
- 网络延迟高时:适当增加线程数
- 目标服务器限制时:添加漏桶算法限流
4. EPUB生成进阶技巧
4.1 样式模板设计
创建epub.css定义阅读样式:
css复制body {
font-family: "Microsoft YaHei", serif;
line-height: 1.8;
margin: 15px;
color: #333;
}
h1 {
font-size: 1.8em;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
p {
text-indent: 2em;
margin: 0.5em 0;
}
通过pandoc命令注入样式:
bash复制pandoc input.txt -o output.epub --css=epub.css --metadata title="小说标题"
4.2 章节自动分页
在Markdown源文件中插入分页符:
markdown复制# 第一章
正文内容...
\pagebreak
# 第二章
5. 数据持久化方案
5.1 SQLite数据库设计
python复制import sqlite3
def init_db():
conn = sqlite3.connect('novels.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS chapters
(id INTEGER PRIMARY KEY,
novel_id INTEGER,
title TEXT,
content TEXT,
url TEXT UNIQUE)''')
conn.commit()
return conn
索引优化建议:
- 为novel_id和url创建索引
- 使用WAL模式提升并发写入性能
- 定期执行VACUUM优化存储空间
5.2 CSV导出功能
python复制import csv
def export_to_csv(novel_id):
with open(f'novel_{novel_id}.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['章节ID', '标题', '字数'])
for chapter in get_chapters(novel_id):
writer.writerow([
chapter['id'],
chapter['title'],
len(chapter['content'])
])
6. 异常处理与监控
6.1 重试机制实现
python复制from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10))
def fetch_with_retry(url):
response = requests.get(url, timeout=10)
response.raise_for_status()
return response
6.2 日志记录配置
python复制import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('downloader.log'),
logging.StreamHandler()
]
)
7. 性能优化实战
通过cProfile分析性能瓶颈:
python复制import cProfile
def run_with_profile():
pr = cProfile.Profile()
pr.enable()
main() # 你的主函数
pr.disable()
pr.print_stats(sort='cumtime')
典型优化案例:
- 发现BeautifulSoup解析耗时占比35% → 改用lxml解析器
- 网络请求占40%时间 → 增加线程池大小
- 数据库写入占20% → 改用批量插入
8. 项目部署方案
8.1 依赖管理
requirements.txt示例:
code复制beautifulsoup4==4.11.1
requests==2.28.1
pandas==1.5.0
python-slugify==6.1.2
pypandoc==1.10
8.2 打包为EXE
使用PyInstaller一键打包:
bash复制pyinstaller --onefile --add-data 'epub.css;.' novel_downloader.py
9. 扩展功能思路
- 自动封面生成:通过PIL库将书名生成图片
- 章节智能合并:根据字数自动分卷
- 云端同步:集成WebDAV实现多设备同步
- 阅读统计:记录阅读进度和时长
这个项目最让我惊喜的是SQLite的WAL模式对多线程写入的性能提升,在开启WAL后,500个章节的并发写入时间从12秒降低到3秒。另外建议在EPUB生成时添加章节导航目录,这个可以通过pandoc的--toc参数自动实现。
