Python 现代开发学习笔记

(十八)暂停、关闭,再从已提交进度继续

1. 比较两次启动实际发出的请求

先保存两本,关闭 SQLite,再打开同一文件继续:

# 项目文件:demos/resume_run.py
# 两次打开同一个进度库;第二次只采剩余详情,目录页和前两本不再重复请求。
import asyncio
from pathlib import Path
from tempfile import TemporaryDirectory

from crawlsite import running_site
from catalogcrawl.runner import crawl
from catalogcrawl.state import CrawlState


if __name__ == "__main__":
    with running_site() as site, TemporaryDirectory() as folder:
        path = Path(folder) / "crawl.sqlite3"
        start = site.base_url + "/catalog/?page=1"
        with CrawlState(path, start) as state:
            asyncio.run(crawl(state, interval=0, stop_after=2))
            print("暂停", state.stats())
        with CrawlState(path, start) as state:
            asyncio.run(crawl(state, interval=0))
            print("恢复", state.stats())
        print("目录请求", site.state.counts["/catalog/"])
        print("第一本请求", site.state.counts["/books/b101"])

第一次输出中,三页目录都已提交,详情完成 2 项、待处理 4 项,items 为 2。第二次详情完成变为 6、待处理为 0、items 为 6。最后的目录请求仍为 3 次,第一本请求仍为 1 次。

第二次启动从 jobs 的 done=0 选择 b103 至 b106,没有重新翻三页目录,也没有重新读取前两本。恢复依据是库里已经提交的任务状态,不是某个仍然活着的 Python 列表。

第一次关闭时两项完成四项待处理,第二次重开从四项待处理继续,并保留前三页发现结果

2. 区分单项失败与本次暂停

如果 b103 持续返回 503,它在本次尝试三次后仍留待处理,其他五本可以先保存。修好服务后再次启动,只选到 b103;成功提交后六本齐全。缺少 h1 的详情也会留待处理,但它已经拿到 HTML,不做三次相同的网络重试。

程序在两项请求之间退出时,已经提交的结果保留;当前批只是取得了响应、还没有提交时,重启后会再读一次这些待处理项。GET 重读与源站编号去重共同让这次重新尝试得到同一组记录。

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