python协程

@TOC协程

啰嗦两句

习惯性啰嗦两句,不论在学习的过程中遇到什么困难,请尽力去解决它,虽然眼下不如意,但是真的要相信越努力的越幸运,只有努力了才能把握机会。我也是小白,也是刚刚起步编程的路上,我觉得不管你现在怎样,最重要的还是看态度问题,你是不是真的想把事情做好,有没有努力去做。自我开始写博客,朋友看了说你写又没人看,为什么还要写呢?我在意的不是有多少人看,而在意的是能否坚持,余晖的某个角落,就是我在偷偷学习的地方。听到最多的就是,你不行,我觉得你不适合。他们说得也许是对的,那是因为我技术不够,你否认了,但是这不代表我放弃,短短几个秋,做自己的喜欢的事就好。我今天又新学了一个东西,协程!

协程

协程使用的是异步技术,那什么叫异步呢?简单来说就是在一个任务没有完成时,也可以执行其他任务——你正在看电影的同时也正在下载电影。我们所知道进程可以有多个线程,而线程又可以有多个协程,最重要的是协程是由程序所控制的!它是一种非抢占式的异步技术,原理就是一个任务在执行过程中,如果遇到等待,就先去执行其他任务,其他任务执行完了,再回来执行之前等待的那个任务。在计算机里,这种任务切换的非常迅速,看起来就像多个任务被同时执行一样。哈哈,我都满满的好奇了!来看看实例吧!

实例

爬虫步骤大家都知道了吧
第一步:找到数据
第二步:解析数据
第三步:提取数据
第四步:保存数据

找到数据

这里选取的网站是美食天下,对于吃货的世界来说,半夜的我目前还在流口水!附上网址:https://www.meishichina.com/。我爬取的是一周热门的食物名称及食料。那就开始吧!等等等!别急,我们先来看看这个网站的robots协议,附上截图
在这里插入图片描述
而我们要爬取的网址没有在robots里面
在这里插入图片描述
那我们开始吧,尝试一下!
老规矩,打开检查看network,可以在👇找到我们想要的数据,并且点开它是GET请求。
在这里插入图片描述
因此它是静态网页,那就好办了,直接打开Elements找到我们想要的数据,可以看到我们想要的数据
在这里插入图片描述

解析数据和提取数据

解析数据我采用的是BS4,当然,css、xpath也行,相对来说css这些速度更快一点,针对性查找。竟然说爬取的是美食网站,那我们就用“汤”嘛!看代码

soup = BeautifulSoup(res.text,'html.parser')
soup_all = soup.find_all('div',class_ = 'detail')
for i in soup_all:
    name = i.find('h2').text #食物名称
    material = i.find('p',class_ = 'subcontent').text #食物原料
    

解析提取数据,就这么简单,当然还可以更深层次的研究,这里只是简单的介绍。

保存数据

保存数据这里不做多余讲解了,csv格式或者text或者保存数据库都可以。

认识协程

协程所需要的模块,打开终端 pip install gevent 下载

from gevent import monkey 
import gevent #导入模块
monkey.patch_all() #猴子补丁,目的实现异步
from gevent.queue import Queue
'''
这里还需要引入队列,为什么呢?gevent不够吗?
'''

这里说一下,为什么要引入队列,队列顾名思义,就是排队等待,如果不引入队列,只使用gevent的话,会存在如果一个爬虫任务停滞,那程序会执行其他任务,但是再回来执行这个任务,你会发现,这个任务也还是原来的样子。图列,自己画的,理解就行了。
在这里插入图片描述
200个请求4个任务,每个任务50个,但是就算其他的任务都完成了,那任务2也还是在意,那怎么解决呢?就是队列了!看看队列是怎么工作的。
在这里插入图片描述
你要爬取的网址,会放在队列里面,让爬虫任务取出来。
大体的一个了解了,我们再回去分析一下网页。

翻页

打开网页,点击下一页,我们会看到第二页的网址是这样的。
在这里插入图片描述
以此类推,page -3 -4 -5 ,那我们找到规律了,就来进行翻页操作

url_1 = 'https://home.meishichina.com/show-top-type-recipe-page-{page}.html'
for i in rnag(5): #选择你要爬取的页数
	url_url_1 = url_1.format(page = i)

完整代码

from gevent import monkey
monkey.patch_all()  #猴子补丁
from gevent.queue import Queue
import requests,gevent,csv
from bs4 import BeautifulSoup

work = Queue()  #创建对象
url_1 = 'https://home.meishichina.com/show-top-type-recipe-page-{page}.html'
for i in range(1,7):
    url_url_1 = url_1.format(page = i)
    work.put_nowait(url_url_1) #把url放进队列里

def crawl(): #函数对应的是解析数据与提取数据
    headers = {
        'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
    while not work.empty(): #当队列不为空时执行一下操作
        url = work.get_nowait() #获取队列里的url
        res = requests.get(url,headers = headers)
        soup = BeautifulSoup(res.text,'html.parser')
        soup_all = soup.find_all('div',class_ = 'detail')
        for i in soup_all:
            name = i.find('h2').text
            material = i.find('p',class_ = 'subcontent').text
            writer.writerow([name,material]) #存入csv

csv_file= open('meishitianxia.csv', 'w', newline='')  #保存数据
writer = csv.writer(csv_file)
writer.writerow(['食物', '原料'])
task_list = []
for i in range(2): #开启两个爬虫任务
    task = gevent.spawn(crawl) #创建任务
    task_list.append(task)
gevent.joinall(task_list)  #执行任务

优点
1.无需线程上下文切换的开销
2.高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

缺点
1.无法利用多核资源,它本质是一个单线程,不能将单个cpu的多核用上。
2.进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

面试考题
计算密集型使用进程,因为进程是直接与cpu沟通的,计算能力强。
I/O密集型使用线程,速度快。

总结

协程三步
一:猴子补丁,目的实现异步技术。何为异步,在一个任务未完成时,就可以执行其他多个任务,彼此不受影响——异步

二:gevent模块,使用它创建任务执行任务。

三:队列(queue),使用队列解决协程缺点阻塞问题,一个一个的来,不要慌!

我还总结了一个,下次写博客不要晚上写,因为你会感受到凌晨4点的寂静,头发的稀疏,嗷,对了,凌晨四点的贵阳还是挺亮的,静静的坐在电脑前,想起那句:月亮不睡我不睡,我是秃头小宝贝。我也不多说了,抓紧睡个好觉,明天又是忙碌的一天!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值