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