🛠️ Python 爬虫实战教学:豆瓣电影 Top250 同步与异步实战手册
前言: 在爬虫领域,效率即生命。当我们需要采集数万条数据时,单线程同步爬取的等待时间是无法接受的。本文将通过实战代码,带你从最基础的同步逻辑演进到极致并发的协程方案。
🛠️ 一、 核心工具栈 (The Toolkit)
本案例的核心逻辑构建在以下几个顶级库之上:
- 数据采集:
requests(同步标准库)/aiohttp(异步高性能库)。 - 数据解析:
lxml (etree)。利用 XPath 语法直接定位 DOM 节点,解析效率远超正则表达式。 - 高性能存储:
DataRecorder。支持多线程/多进程安全写入,自动处理 Excel 文件锁和表头生成。 - 逻辑辅助:
itertools.zip_longest。解决多字段对齐问题,防止因数据缺失导致解析报错。
🧠 二、 代码逻辑深度解析
1. 任务拆分思想 (Task Decoupling)
在并发编程中,不能直接套用同步的 for 循环。我们需要将任务“原子化”:
- 同步逻辑:一个大函数包含从请求、解析到存储的所有步骤。
- 异步/并发逻辑:将“请求一页数据并返回”封装成独立任务,由调度中心(Pool 或 Event Loop)统一分发。
2. 多线程与多进程的差异
- 多进程 (Multiprocessing):利用 OS 级别并行,规避 Python GIL 限制,适合 CPU 密集型任务。
- 多线程 (Threading):在 I/O 等待(网络请求)时自动释放 GIL,资源占用更低,适合爬虫场景。
3. 协程的“分身”原理 (Awaitable)
协程利用 async/await 关键字。当 await 遇到网络延迟时,CPU 会立即跳转执行下一个任务,而不是在那儿“傻等”,这使得单线程也能跑出上千并发。
🚀 三、 全方案代码实战
1. 同步爬取:一步一个脚印
这是所有爬虫的基石,逻辑最清晰,但 I/O 阻塞严重。
- 实测耗时:~7.24s
2. 多进程/多线程:任务池分发
我们将页面索引 range(10) 作为参数传递给池对象。
- 技术点:每个任务执行完后返回
data列表,最后由主进程/主线程统一recorder.record()。 - 实测耗时:~5.79s (多线程) / ~6.95s (多进程)
3. 协程:极致异步
这是目前最优雅的方案。
- 关键点:必须配套异步 HTTP 库
aiohttp。 - 实测耗时:~5.23s
📝 四、 实战运行与优化步骤
第一步:环境配置
安装所有必需依赖,确保 Python 版本 3.6。
第二步:初始化文件管理
在代码中加入 get_excel() 逻辑。每次运行自动清除旧文件,确保数据不重叠且 Excel 不会被占用报错。
第三步:性能调优建议
- 存储优化:将
recorder.record()移出高频循环。建议每爬取完一整页(25条)或全部爬取完后执行一次性写入,可极大降低磁盘 I/O 开销。 - 并发数控制:不要盲目追求高并发。对于豆瓣等网站,建议
max_workers或并发协程数控制在 5-10 个,避免触发反爬机制。
🚀 五、 完整实战源代码整合
1. 同步爬取方案 (基础入门)
特点:逻辑线性,适合初学者理解爬取全过程。
2. 多线程方案 (生产首选)
特点:兼容 requests,通过 ThreadPoolExecutor 快速提速。
多进程方案 (真正的并行)
特点:每个进程拥有独立的 CPU 核心支持,适合需要大量计算(如数据解密、图像处理)的爬虫任务。
3. 协程方案 (极致性能)
特点:单线程下的最高吞吐量,需使用 aiohttp。

