首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第一章:网络爬虫概述与Python基础
第二章:Python网络编程基础
第三章:Python HTTP库的使用
第四章:Python数据存储与文件操作
第五章:Python正则表达式与字符串处理
第六章:Python异常处理与日志记录
第七章:Python多线程与多进程编程
第八章:Python环境搭建与开发工具
第九章:Python爬虫框架的选择与比较
第十章:爬虫的基本原理与技术路线
第十一章:实战一:使用Python基础库编写简单的爬虫
第十二章:实战二:使用Requests库进行网络请求
第十三章:实战三:使用BeautifulSoup解析HTML
第十四章:实战四:使用Scrapy框架进行爬虫开发
第十五章:实战五:使用Selenium模拟浏览器操作
第十六章:实战六:使用Scrapy异步爬虫
第十七章:实战七:使用Scrapy分布式爬虫
第十八章:实战八:使用Scrapy爬虫处理动态网页
第十九章:实战九:使用Scrapy爬虫处理登录验证
第二十章:实战十:使用Scrapy爬虫处理反爬机制
第二十一章:高级技巧一:Python爬虫的性能优化
第二十二章:高级技巧二:Python爬虫的缓存与持久化
第二十三章:高级技巧三:Python爬虫的数据处理与分析
第二十四章:高级技巧四:Python爬虫的并发控制
第二十五章:高级技巧五:Python爬虫的分布式爬虫架构
第二十六章:高级技巧六:Python爬虫的安全性与合规性
第二十七章:高级技巧七:Python爬虫的自动化测试
第二十八章:高级技巧八:Python爬虫的监控与报警
第二十九章:高级技巧九:Python爬虫的异常处理与恢复
第三十章:高级技巧十:Python爬虫的高级特性与技巧
第三十一章:案例分析一:电商平台商品爬取实战
第三十二章:案例分析二:社交媒体数据爬取实战
第三十三章:案例分析三:新闻网站内容爬取实战
第三十四章:案例分析四:科学文献爬取实战
第三十五章:案例分析五:地图数据爬取实战
第三十六章:案例分析六:企业数据爬取实战
第三十七章:案例分析七:招聘网站信息爬取实战
第三十八章:案例分析八:电商网站价格监控实战
第三十九章:案例分析九:旅游网站景点信息爬取实战
第四十章:案例分析十:教育网站资源爬取实战
第四十一章:扩展阅读一:Python爬虫的经典书籍与资源
第四十二章:扩展阅读二:Python爬虫框架比较与选择
第四十三章:扩展阅读三:Python爬虫的最佳实践
第四十四章:扩展阅读四:Python爬虫的安全策略与合规性
第四十五章:扩展阅读五:Python爬虫的性能测试与调优
第四十六章:扩展阅读六:Python爬虫的自动化测试与验证
第四十七章:扩展阅读七:Python爬虫的代码审查与质量控制
第四十八章:扩展阅读八:Python爬虫的持续集成与持续部署
第四十九章:扩展阅读九:Python爬虫开源项目与工具推荐
第五十章:扩展阅读十:从高级程序员到网络爬虫专家之路
第五十一章:高级技巧十一:Python爬虫中的爬虫策略
第五十二章:高级技巧十二:Python爬虫中的数据提取技巧
当前位置:
首页>>
技术小册>>
实战Python网络爬虫
小册名称:实战Python网络爬虫
### 第七章:Python多线程与多进程编程 在网络爬虫的开发过程中,面对大规模数据的抓取任务,单一线程或进程的执行效率往往成为瓶颈。为了提高爬虫的数据抓取速度和效率,Python提供了强大的多线程(threading)和多进程(multiprocessing)编程支持。本章将深入探讨Python中的多线程与多进程编程,理解其原理、适用场景、以及如何在网络爬虫项目中有效应用。 #### 7.1 引言 在网络爬虫领域,多线程和多进程主要用于并行处理多个请求,以缩短总体任务完成时间。虽然Python因其全局解释器锁(GIL)在多线程执行CPU密集型任务时性能受限,但在IO密集型任务(如网络请求)中,多线程依然能显著提升效率。而多进程则通过创建独立的Python解释器实例来绕过GIL的限制,适用于CPU密集型任务或需要更高隔离性的场景。 #### 7.2 Python多线程基础 ##### 7.2.1 线程与进程的区别 - **线程**:是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程中可以拥有多个线程,线程之间共享进程的资源(如内存、文件描述符)。 - **进程**:是系统进行资源分配和调度的一个独立单元,它是应用程序运行的载体。每个进程都有自己独立的内存空间和系统资源。 ##### 7.2.2 Python的threading模块 Python的`threading`模块提供了基本的线程和锁的支持。主要类包括: - `Thread`:表示一个线程的执行实例。 - `Lock`、`RLock`、`Semaphore`、`BoundedSemaphore`、`Event`、`Condition`、`Barrier`等:用于线程间的同步和通信。 ##### 7.2.3 创建与启动线程 ```python import threading def worker(num): """线程工作函数""" print(f'Worker: {num}') threads = [] for i in range(5): t = threading.Thread(target=worker, args=(i,)) threads.append(t) t.start() for t in threads: t.join() ``` #### 7.3 线程同步与互斥 在多线程编程中,由于多个线程共享同一内存空间,可能会导致数据竞争和不一致的问题。因此,需要引入同步机制来保证线程间的有序执行。 ##### 7.3.1 Lock与RLock - `Lock`:基本的锁对象。每次只能有一个线程获得锁,如果线程试图获得一个已经被其他线程持有的锁,则该线程将阻塞,直到锁被释放。 - `RLock`:可重入锁,允许同一个线程多次获得锁。 ##### 7.3.2 Semaphore与BoundedSemaphore - `Semaphore`:信号量,用于控制对共享资源的访问数量。它允许一个或多个线程同时访问某个资源,但总数不能超过设置的限制。 - `BoundedSemaphore`:与Semaphore类似,但会检查所请求的值是否超出了信号量的界限,从而避免程序因错误而请求过多的值。 ##### 7.3.3 Event与Condition - `Event`:事件对象,用于线程间的同步。一个线程可以等待某个事件的发生,而另一个线程可以触发这个事件。 - `Condition`:条件变量,它允许一个或多个线程等待某个条件为真时继续执行。它提供了比Event更高级的同步机制,包括wait()、notify()和notify_all()等方法。 #### 7.4 Python多进程编程 对于CPU密集型任务或需要更高隔离性的场景,Python的`multiprocessing`模块提供了比`threading`更强大的支持。 ##### 7.4.1 Process类 `multiprocessing.Process`是创建新进程的类。与`threading.Thread`类似,但它创建的进程是独立的Python解释器实例,因此不受GIL的限制。 ```python from multiprocessing import Process def worker(num): print(f'Worker: {num} (PID: {os.getpid()})') if __name__ == '__main__': processes = [] for i in range(5): p = Process(target=worker, args=(i,)) processes.append(p) p.start() for p in processes: p.join() ``` 注意:在Windows系统上,启动新的Python进程时必须将代码放在`if __name__ == '__main__':`下,以避免无限递归创建进程。 ##### 7.4.2 进程间通信 由于进程拥有独立的内存空间,因此进程间通信(IPC)需要特殊机制。`multiprocessing`模块提供了多种IPC方式,如队列(Queue)、管道(Pipe)等。 - **Queue**:线程和进程安全的队列实现,用于在多进程间传递消息。 - **Pipe**:用于两个进程之间的双向连接。Pipe()返回一个(conn1, conn2)元组,其中conn1和conn2表示管道的两端,分别由管道的两端使用。 #### 7.5 实战应用:多线程/多进程在网络爬虫中的使用 ##### 7.5.1 场景分析 假设我们需要从一个大型网站上抓取大量数据,每个页面的数据抓取相对独立,但总量巨大。在这种情况下,我们可以使用多线程或多进程来并行抓取,以缩短总耗时。 ##### 7.5.2 设计思路 1. **任务划分**:将总任务划分为多个子任务,每个子任务负责抓取一部分数据。 2. **资源分配**:根据系统资源(CPU核心数、内存大小)决定使用线程还是进程,以及它们的数量。 3. **同步与通信**:如果多个任务需要共享数据或结果,考虑使用合适的同步机制(如锁、队列)来确保数据的一致性和安全性。 4. **异常处理**:为每个任务添加异常处理逻辑,确保单个任务的失败不会影响到整个爬虫程序的运行。 ##### 7.5.3 示例代码 这里以一个简化的网络爬虫为例,展示如何使用`threading`或`multiprocessing`来并行抓取网页内容。 ```python # 假设使用requests库进行网络请求 import requests from threading import Thread from multiprocessing import Process, Queue def fetch_url(url, result_queue): try: response = requests.get(url) result_queue.put((url, response.text)) except Exception as e: result_queue.put((url, str(e))) # 使用多线程 threads = [] result_queue = Queue() urls = ['http://example.com/page1', 'http://example.com/page2', ...] for url in urls: t = Thread(target=fetch_url, args=(url, result_queue)) threads.append(t) t.start() for t in threads: t.join() # 处理结果(略) # 使用多进程(代码结构类似,但使用Process类) # ... ``` #### 7.6 总结 多线程与多进程编程是提升Python程序,尤其是网络爬虫程序性能的重要手段。通过合理利用线程和进程的并发执行特性,可以显著缩短任务完成时间,提高数据抓取效率。然而,在实际应用中,也需要考虑资源限制、数据同步与通信、异常处理等因素,以确保程序的稳定性和可靠性。
上一篇:
第六章:Python异常处理与日志记录
下一篇:
第八章:Python环境搭建与开发工具
该分类下的相关小册推荐:
Python与办公-玩转PPT
Python爬虫入门与实战开发(上)
Python编程轻松进阶(二)
Python合辑14-面向对象编程案例(下)
Python合辑5-格式化字符串
Python合辑3-字符串用法深度总结
Python数据分析与挖掘实战(上)
Python合辑12-面向对象
Python数据分析与挖掘实战(下)
Python机器学习基础教程(上)
Python与办公-玩转Excel
Python机器学习基础教程(下)