普通的python爬虫是单进程单线程的,这样在遇到大量重复的操作时就只能逐个进行,我们就很难过了。举个栗子:你有1000个美图的链接,逐个喂给下载器(函数),看着图片只能一个个蹦出来,你不心急吗?于是我们想,能不能同时跑多个下载器,实现多图同时下载?——答案是可以的,使用多进程/多线程,把每个带着不同参数下载器分给每个进程/线程就,然后同时跑多个进程/线程就行了。
本文就介绍如何用多线程和多进程给爬虫加速
补充主线程与子线程(进程同理):
- 一个py程序就有一个主线程,主线程负责整个py程序的代码,当主线程处理到启用多线程的代码时,就会创建若干个子线程,这里就有选择了,主线程是等待子线程的结束再继续处理还是直接继续处理让子线程在外头跑
Python标准库原本有threading和multiprocessing模块编写相应的多线程/多进程代码。但从Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,实现了对threading和multiprocessing的更高级的抽象,对编写线程池/进程池提供了直接的支持。多进程我们介绍futures的ProcessPoolExecutor注:python 2.7 请安装future模块,pip install future
ProcessPoolExecutor类是Executor类的子类,实例化ProcessPoolExecutor类以创建进程池,在实例化的过程中应指定同时运行的最大进程数
'''
想要学习Python?Python学习交流群:973783996满足你的需求,资料都已经上传群文件,可以自行下载!
'''
from concurrent.futures import ProcessPoolExecutor
pool = ProcessPoolExecutor(max_workers=4) # 运行最大进程数4
#进程池的操作...
pool.shutdown(wait=True) # 关闭进程池,默认等待所有进程的完成。
print('Deep') # 有shutdown的情况下所有进程完成后才会运行下面的print,没有的话会马上运行
'创建进程也可用with,这时会自带shutdown功能
with ProcessPoolExecutor(4) as pool:
#进程池的操作...
'
该类有两种方法对进程池提交任务建立进程(函数及一组参数构成一个任务),分别是submit()
和map()
,如果单纯想多开进程别无他想,用哪个都行,但submit()会有更灵活的用法
- fn:函数
- *iterables:函数每个参数的集合,N个参数就接N个集合
可以理解这是python自带map()的多进程版,他返回的是一个迭代器,包含每个任务对应的返回值(有序的),下面用例子来分析
from concurrent.futures import ProcessPoolExecutor
import time
def test(x):
time.sleep(x) # 时间阻塞
print(str(x)+'s')
return x
if __name__ == '__main__':
with ProcessPoolExecutor(4) as pool:
p = pool.map(test,[2,3,10,5,6])
for i in p:
print(i)
输出
2s
2
3s
3
5s
6s
10s
10
5
6
分析(下面以参数代替某个进程):
- 带s的是函数输出的,进程池最大允许4个进程同时运行,所以参数 2,3,10,5 首先一起进去。2最快完成,马上让给6进去,2+6
关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?