(十九)从采集结果导出 CSV 与书籍库
1. 先确认任务齐全,再复用字段检查
采集进度库保存任务和来源,业务书籍库保存阅读操作。导出时把记录还原成前面使用的 Book,再交给原来的 CSV 与 SQLite 实现:
# 项目文件:crawler_project/src/catalogcrawl/exporting.py
# 采集完成后从进度库重建 Book;再次导出不需要再请求任何页面。
from pathlib import Path
from bookdata.csv_io import write_csv
from bookdata.library import Library
from bookdata.records import validate_books
from .errors import CrawlError
def export_results(state, csv_path: Path, database: Path):
stats = state.stats()
if stats["pages_pending"] or stats["jobs_pending"]:
raise CrawlError("还有待采任务,完成采集后再导出整份目录")
books = validate_books([item.as_record() for item in state.collected()])
# CSV 使用第五章的临时文件替换,业务数据库使用 Library 的整批事务。
write_csv(csv_path, books)
with Library(database) as library:
library.import_books(books)
return len(books)待处理任务没有清空时,函数会反馈具体状态,不覆盖已有导出。任务齐全后,再经过 validate_books 检查整份书目,书名重复等业务冲突会在写出之前被发现。来源信息继续保存在采集库的 items 表中,CSV 仍用第五章的 title、finished、tags 三列。
2. 导出可以从已保存结果重做
CSV 先以临时文件替换完成,随后书籍库通过一次事务导入。若后一步失败,采集进度与书籍记录仍保存在采集库中;修正输出位置后重新执行 export,就可以重新生成两份输出,无须再访问网络。
| 检查项 | 正常完成后的结果 |
|---|---|
| 目录任务 | 3 项完成、0 项待处理 |
| 详情任务 | 6 项完成、0 项待处理 |
| 唯一采集记录 | b101 至 b106,共 6 本 |
| CSV 读取 | 6 份 Book,完成状态 True 共 2 份 |
| SQLite 查询 | 相同六个书名与状态;再次导入仍为 6 本 |