python 协程管理asyncio与异步http库aiohttp

本文介绍了Python中的协程管理库asyncio以及异步HTTP库aiohttp。asyncio提供了一种高效的方式来管理协程,通过async/await语法实现协程间的协作。aiohttp则用于发送HTTP请求,支持GET和POST等方法,并能进行并发请求。文章通过实例展示了如何发起HTTP请求、处理响应内容以及如何封装并发的Http类。
摘要由CSDN通过智能技术生成

1、协程管理——asyncio

协程又称微线程,完全由程序控制,协程切换花销小,因而有更高的性能。

python中使用asynico来作为协程的管理包

python使用asynsawait关键字来进行协程控制

async def work():
    pass

在协程中除了普通函数的功能外最主要的作用就是:使用 await 语法等待另一个协程结束,这将挂起当前协程,直到另一个协程产生结果再继续执行:

async def work(sleepTime):
    await asyncio.sleep(sleepTime)
    print('continue')

asyncio.sleep() 是 asyncio 包内置的协程函数,这里模拟耗时的IO操作,上面这个协程执行到这一句会挂起当前协程而去执行其他协程,直到sleep结束,当有多个协程任务时,这种切换会让它们的IO操作并行处理

执行一个协程函数并不会真正的去运行它,而是会返回一个协程对象

在 Python3.7+ 中,运行asyncio 程序只需要一句:asyncio.run(work()),而在 Python3.6 中,需要手动获取事件循环并加入协程任务:

loop = anyncio.get_event_loop()
loop.run_until_complete(work(1))
loop.close()

事件循环就是一个循环队列,对其中的协程进行调度执行,当把一个协程加入循环,这个协程创建的其他协程都会自动加入到当前事件循环中

其实协程对象也不是直接运行,而是被封装成一个个待执行的 Task ,大多数情况下 asyncio 会帮我们进行封装,我们也可以提前自行封装 Task 来获得对协程更多的控制权

python3.7使用asyncio.create_task()进行封装,而python3.6需要使用asyncio.ensure_future()来进行封装

taskList = [asyncio.create_task(work(num)) for num in range(1, 5)]
# python3.7
task = asyncio.create_task(asyncio.await(taskList))

# python3.6
task = asyncio.ensure_future(asyncio.await(taskList))

协程下面可以套用多层协程,但是每一层必须全部是协程

2、异步http库——aiohttp

asyncio不直接支持http的异步并发请求(只支持tcp与udp请求),因此需要引入异步http库aiohttp

使用pip安装aiohttp

pip3 install aiohttp

aiohttp的用法与requests库很相似

get请求

import aiohttp
import asyncio

"""
    aiohttp:发送http请求
    1.创建一个ClientSession对象
    2.通过ClientSession对象去发送请求(get, post, delete等)
    3.await 异步等待返回结果
"""

async def main():
    url = 'http://httpbin.org/get'
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as res:
            print(res.status)
            print(await res.text())
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)

post请求

import aiohttp
import asyncio

"""
    aiohttp:发送POST请求
"""

async def main():
    data = {'key1': 'value1', 'key2': 'value2'}
    url = 'http://httpbin.org/post'
    async with aiohttp.ClientSession() as session:
        async with session.post(url, data=data) as res:
            print(res.status)
            print(await res.text())
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)

自定义请求头

headers = {'content-type': 'image/gif'}
session.post(url, data=data, headers=headers)

传递参数

import aiohttp
import asyncio

"""
    aiohttp:传递参数
    方式一:通过字典的形式  params = {'key1': 'value1', 'key2': 'value2'}
    方式二:通过二元组的形式  params = [('key', 'value1'), ('key', 'value2')]

"""

async def main():
    url = 'http://httpbin.org/get'
    params = {'key1': 'value1', 'key2': 'value2'}  
    async with aiohttp.ClientSession() as session:
        async with session.get(url, params=params) as res:
            # http://httpbin.org/get?key1=value1&key2=value2
            print(res.url)
            print(await res.text())
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)

状态码与响应内容

import aiohttp
import asyncio

"""
    aiohttp:相应内容与状态码
    状态码:res.status
    响应内容:res.text() 或者 res.text(encoding='utf-8')
    二进制内容:res.read()
    json响应内容:res.json()
    读取流:res.content.read(size)
"""

async def main():
    url = 'https://api.github.com/events'
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as res:
            print(res.status)
            print(await res.text())
            print('**********************************')
            print(await res.read())
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)

封装一个并发的Http类

class Http:
    client = None
    @classmethod
    async def init(cls):
        if cls.client is None:
            cls.client = aiohttp.ClientSession()

    @classmethod
    async def get(cls, *args, **kargs):
        await cls.init()
        return await cls.client.get(*args, **kargs)

    @classmethod
    async def post(cls, *args, **kargs):
        await cls.init()
        return await cls.client.post(*args, **kargs)

    @classmethod
    async def close(cls):
        if cls.client is not None:
            await cls.client.close()
            cls.client = None

参考

python协程之asyncio

Python之异步http库–aiohttp

使用asyncio + aiohttp实现异步的requests API接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值