Python 现代开发学习笔记

(十九)从采集结果导出 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 本
采集库保留完整记录,CSV与业务库分别输出,写库失败后从采集库重做导出而不重新请求

笔记正文与全部题解 · Ctrl / ⌘ K