爬虫学习笔记(补充内容)异步编程

13 篇文章 4 订阅


前言

2021.09.01完成最后部分的学习,
文章中的图片代码后期复习的时候会敲出来进行修改。


补充内容:

协程 & asyncio & 异步

异步编程(课程简介)

  • 为什么要讲?
    • 越来越多的人关心async异步相关问题,并且该部分知识点不易学习(异步非阻塞、asyncio)
    • 异步相关话题和框架越来越多,例如:tornado、fastapi、django 3.x asgi、 aiohttp都在异步–>提升性能
  • 课程大纲
    • 第一部分:协程
    • 第二部分:asyncio模块进行异步编程
    • 第三部分:实战案例

1.协程

  • 协程不是计算机提供,程序员人为创造
  • 协程(Coroutine),也可以被称为微线程,是一种用户态内的上下文切换技术。简而言之,其实就是通过一个线程实现代码块相互切换执行。例如:
def func1():
	print(1)
	...
	print(2)

def func2():
	print(3)
	...
	print(4)

func1()
func2()
  • 实现协程的方法:
    • greenlet,早期模块
    • yied关键字
    • asyncio装饰器(py3.4)
    • async、await关键字(py3.5)【推荐】(主流)

1.1greenlet实现协程

  • pip install greenlet
  • 示例代码如下:
    在这里插入图片描述

1.2 yield关键字

  • 示例代码如下:
    在这里插入图片描述

1.3asyncio

  • 在python3.4及之后的版本。
    在这里插入图片描述

  • 注意:遇到IO阻塞自动切换

1.4async & await 关键字

  • 在python3.5及之后的版本。
  • 将上面1.3中的代码稍加修改:
    • 函数前添加async修饰器
    • yield from 改为 await
      在这里插入图片描述

2.协程的意义

  • 在一个线程中遇到IO等待时间,线程不会干等,会利用空闲时间做其他事。
  • 案例:下载3张图片
    • 普通方式(同步):
      pip install requests
      在这里插入图片描述
    • 协程方式(异步):
      在这里插入图片描述

3.异步编程

3.1 事件循环

  • 理解成死循环,检测并执行某些代码
    在这里插入图片描述
import asyncio

# 生成或获取一个事件循环
loop = asyncio.get_event_loop()

# 将任务放到任务列表
loop.run_until_complete(任务)

3.2 快速上手

  • 协程函数:定义函数时 async def 函数名
  • 协程对象:执行 协程函数() 得到的协程对象
async def func():
	pass

result = func()
  • 注意:执行协程函数创建协程对象,函数内部代码不会执行
  • 如果想要运行协程函数内部代码,必须要将协程对象交给事件来循环处理
import asyncio

async def func():
	print("test-1")

result = func()

# python3.7之前
loop = asyncio.get_event_loop()
loop.run_until_complete(result)
# python3.7之后
asyncio.run(result)

3.3 await

  • await + 可等待的对象(协程对象、Future、Task对象–>IO等待)

示例1:

import asyncio
async def func():
	print("come on~")
	response = await asyncio.sleep(2) 	# 模拟网络请求
	print("over!", response)

asyncio.run( func() )

示例2:

import asyncio

async def others():
	print("start")
	await asyncio.sleep(2) 
	print("over!")
	return '返回值'

async def func():
	print('执行协程函数内部代码'# 遇到IO操作挂起当前协程(任务),等待IO操作完成之后再继续向下执行
	# 当前协程挂起时,事件循环可以去执行其他协程(任务)
	response = await others()

	print('IO请求结束,结果为:', response)
	
asyncio.run( func() )

示例3:

import asyncio

async def others():
	print("start")
	await asyncio.sleep(2) 
	print("over!")
	return '返回值'

async def func():
	print('执行协程函数内部代码'# 遇到IO操作挂起当前协程(任务),等待IO操作完成之后再继续向下执行
	# 当前协程挂起时,事件循环可以去执行其他协程(任务)
	response1 = await others()
	print('IO请求结束,结果为:', response1)
	
	response2 = await others()
	print('IO请求结束,结果为:', response2)
	
asyncio.run( func() )
  • await就是等待对象的值得到结果之后再继续进行

3.4 Task对象

  • 在事件循环中添加多个任务
    • task用于并发调度协程,通过asyncio.create_task(协程对象)的方式创建Task对象,这样可以让协程加入事件循环中等待被调度执行,除了使用asyncio.create_task(协程对象)函数(3.7之后才能使用)外,可以使用loop.create_task()或者ensure_future()函数。不建议手动实例化Task对象。

示例1:
在这里插入图片描述

示例2:

在这里插入图片描述
示例3:
在这里插入图片描述

3.5 asyncio.Future对象

  • Task继承Future,task对象内部await结果的处理基于future
    示例1:
    在这里插入图片描述
    示例2:
    在这里插入图片描述

3.6 concurrent.futures.Future对象

  • 该future对象和上一个future对象无关

  • 使用线程池、进程池实现异步操作时用到的对象
    在这里插入图片描述

  • 以后写代码可能会存在交叉时间。例如:crm项目80%都是基于异步协程 + MySQL(不支持)【线程、进程做异步编程】

  • future的转换: fut = loop.run_in_executor(None, func1)
    在这里插入图片描述

  • 案例:asyncio + 不支持异步的模块
    在这里插入图片描述

3.7异步迭代器

  • 迭代器:
    在其内部实现yield方法和next方法的对象。
  • 可迭代对象:在类内部实现一个iter方法,并返回一个迭代器。
  • 异步迭代器
    实现了__aiter__()__anext__()方法的对象,必须返回一个awaitable对象。async_for支持处理异步迭代器的
    __anext__()方法返回的可等待对象,直到引发一个stopAsyncIteration异常,这个改动由PEP 492引入。
  • 异步可迭代对象
    可在async_for语句中被使用的对象,必须通过它的__aiter__()方法返回一个asynchronous_iterator(异步迭代器)。这个改动由PEP 492引入。
    在这里插入图片描述

3.8异步上下文管理器

  • 上下文管理器:
    with open时 :enter,exit。

  • 异步上下文管理器:
    通过定义__aenter__()__aexit__()方法来对async_with语句中的环境进行控制。
    在这里插入图片描述

4.uvloop

  • uvloop:是asyncio的事件循环的替代方案。事件循环效率>默认asyncio的事件循环。
  • pip install uvloop
    在这里插入图片描述
    注意:一个asgi–>uvicorn 内部使用的就是uvloop

5.实战案例

5.1 异步redis

  • 再通过Python代码操作redis时,链接/操作/断开都是网络IO。
  • pip install aioredis
    示例1:
    在这里插入图片描述示例2:
    在这里插入图片描述

5.2 异步MySQL

  • pip install aiomysql
    示例1:
    在这里插入图片描述
    示例2:
    在这里插入图片描述

5.3 FastAPI框架

  • pip install fastapi
  • pip install uvicorn(asgi内部基于uvloop)

示例(luffy.py):
在这里插入图片描述

5.4 爬虫

  • pip install aiohttp
    在这里插入图片描述

总结

  • 最大的意义:通过一个线程利用其IO等待时间去做一些其他事情。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

竹清兰香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值