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

导读:本篇文章讲解 使用gevent库+queue模块实现多协程爬虫,提高爬取效率!,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

 

协程是干什么的?

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

代码解析:

使用简单代码讲解

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

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)+'秒')  # 相减即可获取运行时间

运行结果如下:

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

 

去掉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)+'秒')

运行结果如下:

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

从结果查看:

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

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

 

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

 

 

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

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

 

-END-

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/66985.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!