爬虫六、gevent协程与queue模块

本文介绍了如何使用gevent库和queue模块实现Python协程爬虫。首先,通过pip安装gevent,并使用monkey.patch_all()打补丁以实现异步爬虫。接着,展示了gevent.spawn()创建并启动协程任务的例子,以及gevent.joinall()执行所有任务。此外,还介绍了在多协程爬虫中,queue模块作为有序数据结构用于存储和管理任务,确保任务按序执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gevent库与协程

安装方法:window电脑:在终端输入命令:pip install gevent;mac电脑:在终端输入命令:pip3 install gevent.
在导入其他库和模块前,先把monkey模块导入进来,并运行monkey.patch_all()。这样,才能先给程序打上补丁。

它的原理是:一个任务在执行过程中,如果遇到等待,就先去执行其他的任务,当等待结束,再回来继续之前的那个任务。在计算机的世界,这种任务来回切换得非常快速,看上去就像多个任务在被同时执行一样,相当于同时发起了多个请求。即实现了异步的爬虫方式达到多协程的目的,gevent库就能实现这个功能。
代码示例:

from gevent import monkey
#从gevent库里导入monkey模块。
monkey.patch_all()
#monkey.patch_all()能把程序变成协作式运行,就是可以帮助程序实现异步。
import gevent,time,requests
#导入gevent、time、requests。
start = time.time()
#记录程序开始时间。

url_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/']
#把8个网站封装成列表。
def crawler(url):
#定义一个crawler()函数。
    r = requests.get(url)
    #用requests.get()函数爬取网站。
    print(url,r.status_code)
    #打印网址、请求状态码。
tasks_list = [ ]
#创建空的任务列表。

for url in url_list:
#遍历url_list。
    task = gevent.spawn(crawler,url)
    #用gevent.spawn()函数创建任务。
    tasks_list.append(task)
    #往任务列表添加任务。
gevent.joinall(tasks_list)
#执行任务列表里的所有任务,就是让爬虫开始爬取网站。    
end = time.time()
#记录程序结束时间。
print(end-start)
#打印程序最终所需时间。

gevent.spawn()的参数应为要调用的函数名及该函数的参数。比如,gevent.spawn(crawler,url)就是创建一个执行crawler函数的任务,参数为crawler函数名和它自身的参数url。调用gevent库里的joinall方法,能启动执行所有的任务。gevent.joinall(tasks_list)就是执行tasks_list这个任务列表里的所有任务,开始爬取。
在这里插入图片描述以上涉及单词的注音及原意:
monkey—[ˈmʌŋki] 猴子
patch—[pætʃ] 补丁
spawn—[spɔːn] 产卵
join-- [dʒɔin] 加入----(joinall–联合)
task-- [tɑːsk] 任务
queue---- [kjuː] 排队\队列

queue模块

当我们用多协程来爬虫,需要创建大量任务时,我们可以借助queue模块。用queue模块来存储任务,让任务都变成一条整齐的队列,因为queue其实是一种有序的数据结构,可以用来存取数据。这样,协程就可以从队列里把任务提取出来执行,直到队列空了,任务也就处理完了。
示例代码:

第1部分是导入模块。

from gevent import monkey
#从gevent库里导入monkey模块。
monkey.patch_all()
#monkey.patch_all()能把程序变成协作式运行,就是可以帮助程序实现异步。
import gevent,time,requests
#导入gevent、time、requests
from gevent.queue import Queue
#从gevent库里导入queue模块

**2部分,是如何创建队列,以及怎么把任务存储进队列里。**
start = time.time()
#记录程序开始时间

url_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()
#创建队列对象,并赋值给work。
for url in url_list:
#遍历url_list
    work.put_nowait(url)
    #用put_nowait()函数可以把网址都放进队列里。用Queue()创建queue对象,相当于创建了一个不限任何存储数量的空队列。如果往Queue()中传入参数,比如Queue(10),则表示这个队列只能存储10个任务。创建了queue对象后,我们就能调用这个对象的put_nowait方法,把我们的每个网址都存储进我们刚刚建立好的空队列里  
#work.put_nowait(url)这行代码就是把遍历的8个网站,都存储进队列里。

**#第3部分,定义爬取函数以及如何从队列里提取出刚刚存储进去的网址:**
def crawler():
    while not work.empty():
    #当队列不是空的时候,就执行下面的程序。
        url = work.get_nowait()
        #用get_nowait()函数可以把队列里的网址都取出。
        r = requests.get(url)
        #用requests.get()函数抓取网址。
        print(url,work.qsize(),r.status_code)
        #打印网址、队列长度、抓取请求的状态码。
#上面代码涉及到queue对象的三个方法:empty方法,是用来判断队列是不是空了的;get_nowait方法,是用来从队列里提取数据的;qsize方法,是用来判断队列里还剩多少数量的。

**#第4部分让爬虫用多协程执行任务,爬取队列里的8个网站的代码:**
tasks_list  = [ ]#创建空的任务列表
for x in range(2):
#相当于创建了2个爬虫
    task = gevent.spawn(crawler)
    #用gevent.spawn()函数创建执行crawler()函数的任务。
    tasks_list.append(task)
    #往任务列表添加任务。
gevent.joinall(tasks_list)
#用gevent.joinall方法,执行任务列表里的所有任务,就是让爬虫开始爬取网站。
end = time.time()
print(end-start)

在这里插入图片描述
empty()— [ˈempti] 空的
full()— [fʊl] 满的
在这里插入图片描述
本内容由博主从风变学习网站学习整理而来,风变网页为:www.pypypy.cn

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值