商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Python爬虫怎么实现断点续传_基于SQLite记录已抓取URL实现

Python爬虫怎么实现断点续传_基于SQLite记录已抓取URL实现

  发布于2026-07-20 阅读(0)

扫一扫,手机访问

爬虫的断点续传功能,核心在于如何准确记录已抓取的URL,避免重复劳动。用SQLite来实现,比用文件记录的方式稳定得多,这背后涉及事务、并发控制和状态管理,并非简单的存储问题。下面拆解几个关键操作点,希望对你有帮助。

为什么直接用文件记录URL续传容易出错

用纯文本或JSON存已抓取URL,乍一看确实简单,但并发写入时很容易出问题:丢数据、重复抓取,甚至文件损坏。SQLite自带事务和行级锁,INSERT OR IGNORE能天然防重,SELECT COUNT(*)查进度也快——这可不是过度设计,而是爬虫跑一两天后不崩溃的底线。

建表语句必须包含这三列

只存URL不够。断点续传依赖三个关键状态字段:url(主键)、status('pending'/'done'/'error')、updated_at(时间戳)。示例:

CREATE TABLE IF NOT EXISTS crawl_queue (    url TEXT PRIMARY KEY,    status TEXT NOT NULL DEFAULT 'pending',    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);

要是漏掉PRIMARY KEY,重复插入就直接失败;没DEFAULT 'pending',新URL状态为空,后续WHERE status = 'pending'查不到;时间戳不设默认值,就无法判断哪批URL是上一次中断前插入的。

每次请求前必须先标记为 pending

不能“先请求再入库”,否则程序崩在中间,这个URL就永远卡在“未记录”状态,下次启动直接重抓。正确顺序是:

立即学习“Python免费学习笔记(深入)”;

  • 从数据库取一条status = 'pending'的URL
  • UPDATE crawl_queue SET status = 'pending', updated_at = CURRENT_TIMESTAMP WHERE url = ?抢占式标记(避免多进程抢同一URL)
  • 真正发起HTTP请求
  • 成功则UPDATE ... SET status = 'done',失败则SET status = 'error'

注意:UPDATE必须带WHERE url = ?且用参数化查询,否则可能误标其他URL;updated_at每次更新都要重置,方便按时间排查卡住的任务。

重启时如何安全跳过已抓取内容

别用SELECT * FROM crawl_queue WHERE status != 'done'当待抓队列——如果某URL状态是'error',你可能还想重试,但直接过滤掉就丢了。更稳妥的做法是:

  • 启动时执行UPDATE crawl_queue SET status = 'pending' WHERE status = 'error' AND updated_at < datetime('now', '-1 hour')(给错误项1小时冷却)
  • 然后只取status = 'pending'的URL
  • 如果要彻底跳过历史成功项,确保解析逻辑里有if row['status'] == 'done': continue,而不是靠SQL过滤

很多人忽略updated_at的时间条件,导致网络超时的错误任务被无限重试,压垮目标站点。

实际跑起来后,最麻烦的不是SQL怎么写,而是网络IO和数据库写入速度不匹配——加个time.sleep(0.1)比优化SQL更能防止被封,而SQLite的WAL模式开启与否,直接影响并发读写时的锁等待时间。

本文转载于:https://www.php.cn/faq/2324031.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注