Python aiohttp 库是否值得学?那必须要掌握呀

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

aiohttp 是一个基于 asyncio 的异步 HTTP 客户端/服务器库。它提供了一组用于编写高性能异步网络应用程序的工具包括基于协程的客户端和服务器。
库的安装使用 pip install aiohttp

Python aiohttp 库

通过 aiohttp 搭建服务器

掌握该库的入门案例就是搭建 aiohttp 服务器示例代码如下

from aiohttp import web


async def handle(request):
    name = request.match_info.get('name', "dream_ca")
    text = "你好, " + name
    return web.Response(text=text)


app = web.Application()
app.add_routes([web.get('/{name}', handle)])

web.run_app(app)

运行之后该服务器会监听本地 8080 端口然后访问 127.0.0.1:8080/ca 就可以得到下图所示内容。
Python aiohttp 库是否值得学那必须要掌握呀
Python aiohttp 库是否值得学那必须要掌握呀
继续扩展 aiohttp 库在服务器端的应用。

aiohttp 路由

aiohttp 提供了一个 WebApplication 类来处理路由它具有一些方法来处理特定的 HTTP 方法如 GETPOST 和 DELETE。下面是一个示例代码

from aiohttp import web


# 创建一个处理GET请求的函数
async def handle_get(request):
    name = request.match_info.get('name', "梦想橡皮擦")
    text = "你好, " + name
    return web.Response(text=text)


# 创建一个处理POST请求的函数
async def handle_post(request):
    data = await request.json()
    text = f"你好, {data['name']}"
    return web.Response(text=text)


app = web.Application()

# 使用 app.router.add_get() 方法来处理GET请求
app.router.add_get('/{name}', handle_get)

# 使用 app.router.add_post() 方法来处理POST请求
app.router.add_post('/', handle_post)

web.run_app(app)

在上述代码中使用 app.router.add_get() 方法来处理 GET 请求并使用 app.router.add_post() 方法来处理 POST 请求。这两个方法都接受两个参数:一个是路由路径另一个是处理该路由的函数。如果请求的 URL 匹配路由路径aiohttp 将调用相应的处理程序来处理请求。

除此之外request.match_info.get() 函数是 aiohttp 库中用来获取路由中变量部分的值的对象。它是一个字典类型键是路由中变量的名称值是请求 URL 中对应的值。

在路由中变量部分通常用花括号 {} 来表示如下所示

app.router.add_get('/users/{user_id}', handle_get_user)

在上述代码中路由是 '/users/{user_id}' 其中 {user_id} 是一个变量。当请求 URL 为 '/users/666'request.match_info 就会返回一个字典其中包含一个键 'user_id' 和值 '666'

你可以使用 match_info.get(name, default) 来获取路由中变量的值其中 name 是变量的名称default 是默认值。如果变量名称不存在则返回默认值。

aiohttp 中还可以使用 app.add_routes() 一次性添加多个路由。

from aiohttp import web


async def handle_index(request):
    return web.Response(text="index 页面")


async def handle_about(request):
    return web.Response(text="about 页面")


async def handle_i(request):
    return web.Response(text="i 页面")


app = web.Application()

app.add_routes([web.get('/', handle_index),
                web.get('/about', handle_about),
                web.post('/i', handle_i)])

web.run_app(app, host='127.0.0.1')

aiohttp 中间件

aiohttp 的中间件是一种组件它可以在请求/响应处理过程中插入额外的逻辑。它可以在请求和响应之间插入额外的处理并允许对请求和响应进行更改。

中间件的工作方式是在请求到达应用程序之前先经过中间件的处理再到达应用程序的处理函数最后响应经过中间件的处理后返回给客户端。

请求->中间件->应用程序处理->中间件->响应

下面演示如何使用中间件添加响应计时功能代码如下

from aiohttp import web
import time


async def handle_index(request):
    time.sleep(1)
    return web.Response(text="index 页面")


async def handle_about(request):
    time.sleep(5)
    return web.Response(text="about 页面")


async def handle_i(request):
    time.sleep(10)
    return web.Response(text="i 页面")


# 定义一个中间件
async def timer_middleware(app, handler):
    async def middleware_handler(request):
        start_time = time.time()
        response = await handler(request)
        end_time = time.time()
        print(f"请求响应时间 {end_time - start_time} ")
        return response

    return middleware_handler


app = web.Application()

# 使用中间件
app = web.Application(middlewares=[timer_middleware])

app.add_routes([web.get('/', handle_index),
                web.get('/about', handle_about),
                web.post('/i', handle_i)])

web.run_app(app, host='127.0.0.1')

Python aiohttp 库是否值得学那必须要掌握呀
上述代码我们定义了一个名为 timer_middleware 的中间件它接受两个参数apphandler。 app 是 aiohttp 的应用程序实例 handler 是要处理请求的函数。

中间件的逻辑是在处理请求之前记录当前时间然后调用传入的处理函数来处理请求最后记录当前时间并计算请求处理时间。

最后我们使用 app.middlewares 属性来添加中间件这样就可以在请求处理之前和之后计算时间了。

中间件可以用于许多其他用途如

  • 验证身份
  • 添加额外的请求头
  • 捕获和处理异常
  • 记录请求日志
  • 对响应进行处理

aiohttp 发送异步 HTTP 请求

在爬虫领域使用 aiohttp 更多的是发送异步请求。

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()


async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'https://baidu.com')
        print(html)


if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())

如果希望调用 aiohttp 库还需要配合协程库 asyncio该库的学习可以阅读橡皮擦的另一篇博客。

《Python 协程学习有点难度这篇文字值得你去收藏》

aiohttp 发送多个异步 HTTP 请求

如果想要提高爬虫采集速度可以搭配 asyncio.wait() 进行提速。

import aiohttp
import asyncio


async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()


async def main():
    async with aiohttp.ClientSession() as session:
        tasks = []
        tasks.append(asyncio.ensure_future(fetch(session, 'https://baidu.com')))
        tasks.append(asyncio.ensure_future(fetch(session, 'https://sogou.com')))
        tasks.append(asyncio.ensure_future(fetch(session, 'https://so.com')))
        done, pending = await asyncio.wait(tasks)
        for task in done:
            print(task.result())


if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())

在这个代码的基础上我们可以继续使用 aiohttp 库提供的扩展功能来编写异步网络程序。详细的扩展功能如下所示。

  • 使用 aiohttp.ClientSession 类可以进行异步请求这个类提供了多种方法来发起请求如 get、post、put、delete 等。
  • 使用 aiohttp.TCPConnector 可以连接池管理这个类允许你控制并发连接的数量以及重用连接。
  • 使用 aiohttp.ClientTimeout 类可以设置超时时间这个类可以设置 connect_timeout、read_timeout 和 total_timeout 三个属性来控制连接和读取超时时间。
  • 使用 aiohttp.ClientSession.request() 方法可以进行自定义请求这个方法允许你设置请求的 method、url、headers 等参数。
  • 使用 aiohttp.ClientSession.post() 方法可以实现文件上传使用 aiohttp.ClientSession.get() 方法可以实现文件下载。
  • 使用 aiohttp.ClientSession.request() 方法可以设置请求的高级选项如请求的身份验证、代理、重定向、请求超时等。
  • 使用 aiohttp.ClientSession.ws_connect() 方法可以建立 WebSockets 连接并使用 async for 来接收消息。

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕可以点点小手赞一下
🌻 发现错误直接评论区中指正吧
📆 橡皮擦的第 832 篇原创博客

从订购之日起案例 5 年内保证更新

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python