python3协程 queue_使用gevent库+queue模块实现多协程爬虫,提高爬取效率!

协程是干什么的?

协程可以提高任务执行的效率!它的执行原理就是当计算机在执行某个任务的时候,如果需要等待(比如爬取网站需要等待网站响应等),可以先去执行其他的任务,等等待结束(网站响应)时,再回来继续任务。本质上就是减少等待的时间,提高爬取的效率。

代码解析:

使用简单代码讲解

接下来来看看这么实现它,先用一个比较简单的代码来看看:

from gevent import monkey

monkey.patch_all()

import gevent

from gevent.queue import Queue

list = [1,2,3,4,5,6]

work = Queue()

for i in list:

work.put_nowait(i)

def crawler():

while not work.empty():

num = work.get_nowait()

print(num,work.qsize())

tasks_list = [ ]

for x in range(2):

task = gevent.spawn(crawler)

tasks_list.append(task)

gevent.joinall(tasks_list)

基本知识点讲解:

第1行:从gevent库里导入monkey模块;

第2行:monkey.patch_all()能把程序变成协作式运行;

第3行:调用gevent库;

第4行:调用queue模块中的Queue类;

第7行:实例化Queue类,创建一个队列;

第8行:遍历列表中的元素;

第9行:Queue.put_nowait()方法是把列表中的元素依次加入队列中;

第11~14行:创建crawler函数

Queue.empty()判断队列是否为空,空返回True;

Queue.get_nowait()从队列中取值(即第9行添加的值);

Queue.qsize()返回队列的长度。

第16行:创建空列表tasks_list,用于后面添加任务;

第17~19:创建2个协程,创建任务并把任务添加到任务列表中

gevent.spawn(crawler)创建任务,这里传入的是函数名;

第20行:gevent.joinall(tasks_list)执行任务。

使用爬虫代码测试

接下来通过爬取8个网站来做一下测试:

from gevent import monkey

monkey.patch_all()

import gevent,requests

from gevent.queue import Queue

list = ['https://www.baidu.com/',

'https://www.sina.com.cn/',

'http://www.sohu.com/',

'https://www.qq.com/',

'https://www.163.com/',

'http://www.iqiyi.com/',

'https://www.tmall.com/',

'http://www.ifeng.com/']

work = Queue()

for url in list:

work.put_nowait(url)

def crawler():

while not work.empty():

url = work.get_nowait()

res = requests.get(url)

print(url,work.qsize(),res.status_code) # 打印网址,队列长度,请求返回情况

tasks_list = []

for x in range(2):

task = gevent.spawn(crawler)

tasks_list.append(task)

gevent.joinall(tasks_list)

那么,怎么看效率提高了呢?

3

2

1

0 揭晓答案:

可以调用time模块的time()方法来计算,代码如下:

from gevent import monkey

monkey.patch_all()

import gevent,requests,time

from gevent.queue import Queue

start = time.time() # 获取开始运行时间戮

list = ['https://www.baidu.com/',

'https://www.sina.com.cn/',

'http://www.sohu.com/',

'https://www.qq.com/',

'https://www.163.com/',

'http://www.iqiyi.com/',

'https://www.tmall.com/',

'http://www.ifeng.com/']

work = Queue()

for url in list:

work.put_nowait(url)

def crawler():

while not work.empty():

url = work.get_nowait()

res = requests.get(url)

print(url, work.qsize(), res.status_code)

tasks_list = []

for x in range(2):

task = gevent.spawn(crawler)

tasks_list.append(task)

gevent.joinall(tasks_list)

end = time.time() # 获取运行结束时间戮

print('运行耗时'+str(end-start)+'秒') # 相减即可获取运行时间

运行结果如下:

e8948bfdf60ab502730b934646f1b4bd.png

去掉gevent库,测试一下运行时间:

import requests,time

start = time.time()

def crawler(url):

res = requests.get(url)

print(url, res.status_code)

list = ['https://www.baidu.com/',

'https://www.sina.com.cn/',

'http://www.sohu.com/',

'https://www.qq.com/',

'https://www.163.com/',

'http://www.iqiyi.com/',

'https://www.tmall.com/',

'http://www.ifeng.com/']

for url in list:

crawler(url)

end = time.time()

print('运行耗时'+str(end-start)+'秒')

运行结果如下:

edbf093bd52f7304d912ab3c472fcabe.png

从结果查看:

有gevent库+queue模块时运行只需要1.96秒左右;

没有gevent库+queue模块时运行需要4.02秒左右。

当然,这不代表使用gevent库+queue模块速度可以减少一半,只能说明使用gevent库+queue模块能够很好的提高效率!

注意:当crawler()函数有参数的时候,gevent.spawn()这个函数传入的参数为gevent.spawn(函数名,参数)。传函数名即可,不用加括号(加括号变成了调用函数,传入的是函数的返回值),然后函数的参数,跟在后面,spawn()会把参数传进函数进行调用。

如果crawler()函数没有有参数,则直接使用gevent.spawn(函数名)即可。

-END-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值