协程★★★★★

### 协程

#进程:资源划分的最小单位(划分的地)
#线程:执行调度的最小单位(工人)
#协程是线程的一种实现方式(协程是工人的办事方法,在一个线程里分为好多协程,基于上次状态往下做,底成基于yield)
#主线程执行完毕就结束,不会等到协程执行完(要加join),工人没了,方法就不存在了,



基本语法:
引入:from gevent import monkey   ==>把下面所有引入的模块中的阻塞识别一下
	 monkey.patch_all() 
	 import gevent 

spawn(函数,参数1,参数2,参数3 .... )  启动协程  ==>在哪些函数进行切换(在一个线程里面执行,有几个函数切换就启动几个协程,线程池是执行多少个线程返回一个对象)
join 阻塞,直到某个协程任务执行完毕之后,再放行
joinall 等待所有协程任务都执行完毕之后,在放行
g1.join()  g2.join()   <=>  gevent.joinall( [g1,g2] )(推荐:比较简洁)
value 获取协程任务中的返回值 g1.value g2.value 获取对应协程中的返回值  
语句和语句之间可以用分好;隔开写在一行;

例如:
def eat():
	print("eat 1")
	time.sleep(3)
	print("eat 2")
	return "吃完了"

def play():
	print("play one")	
	time.sleep(3)
	print("play two")
	return "玩完了"

利用gevent.spawn创建协程对象g1
g1 = gevent.spawn(eat)
利用gevent.spawn创建协程对象g2
g2 = gevent.spawn(play)

默认:主线程不会等待所有的协程都执行完毕就会终止程序
等待g1 g2协程任务完毕之后再向下执行;
gevent.joinall( [g1,g2] ) # 一个列表参数(joinall只接受一个参数)
print("主线程执行结束 ... ")

print(g1.value)
print(g2.value)

在这里插入图片描述

用协程改成一下生产者消费者模型

def producer():
	# 数据范围0 ~ 999
	for i in range(1000):
		yield i
	
def counsumer(gen):
	for i in range(10):
		print(next(gen))
初始化生成器函数
gen = producer()	
counsumer(gen)
counsumer(gen)
counsumer(gen)

协程的例子(利用协程爬取数据)

"""requests 抓取页面数据模块"""
HTTP 状态码  ==>超文本传输协议(不单单可以传文件,可以传音频,视频,图片)
#一个客户端向另外一个服务端访问.一定会经过三次握手的
服务端返回的状态码:
200 ok  ==>请求成功
404 not found  ==>网页走丢了(访问到了,地址可以,页面没有)
400 bad request ==>失败的请求(访问不到了)


基本语法

爬取数据:
第一步:
要抓取哪一个网站
response = requests.get("http://www.baidu.com")  ==>必须协议加域名
#response 响应(是一个对象)
print(response)
第二步:
获取状态码  ==>一定要检验是否能够抓取对方的页面内容
print( response.status_code )
第三步:
获取当前网页中的字符编码(对方使用什么编码集)
res = response.apparent_encoding
print( res )
第四步:
设置编码集,防止乱码
response.encoding = res  ==>将自己的编码集也设置成对方的编码集
第五步;
获取网页当中的内容
res = response.text
print(res)
#如果没有直接获取到内容,先新建文件(文件名加html),在pycharm中打开,直接复制结果到pycharm中,然后将文件拖到浏览网页即可





如果爬的网站比较多,可以塞到一个列表里:
url_list = [
"http://www.baidu.com",
"http://www.4399.com/",
"http://www.7k7k.com/",
"http://www.jingdong.com/"
]

正常爬取:
import requests
def get_url(url):
	response = requests.get(url)
	if response.status_code == 200:
		 print(response.text)
for i in url_list:
	get_url(i)


爬完以后扣取网站,用正则匹配:
import re
strvar = '<img lz_src="http://i5.7k7kimg.cn/cms/cms10/20200609/113159_2868.jpg"'
obj = re.search(r'<img lz_src="(.*?)"',strvar)
print(obj.groups()[0])

用协程的方式爬取数据(更多网站,大数据)★★★★★

from gevent import monkey ; monkey.patch_all()
import gevent
import requests

如果爬的网站比较多,可以塞到一个列表里:
url_list = [
"http://www.baidu.com",
"http://www.4399.com/",
"http://www.7k7k.com/",
"http://www.jingdong.com/"
.....
]

def get_url(url): 爬取函数
	response = requests.get(url)
	if response.status_code == 200:
		 print(response.text) 
for i in url_list: ==>遍历爬取对象
	lst = []
	g = gevent.spawn(get_url,i)  ==>利用多协程执行
	lst.append(g)  ===>如果爬取的比较多,要塞到列表里面

gevent.joinall(lst)  ===>joinall正好需要的是列表,如果有多个参数,要用列表括起来
print("执行时间:" ,endtime - starttime ) # 执行时间: 2.3307271003723145


利用好多进程,多线程,多协程可以让服务期运行速度更快,
并且也可以抗住更多用户的访问;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值