aiohttp簡介與簡單使用


簡介

aiohttp是一個為Python提供異步HTTP客戶端/服務端編程,基於asyncio(Python用於支持異步編程的標准庫)的異步庫

核心功能

  • 同時支持客戶端使用和服務端使用
  • 同時支持服務端WebSockets組件和客戶端WebSockets組件
  • web服務器具有中間件、信號組件和可插撥路由的功能

安裝

安裝命令如下(推薦使用python3.7或以上版本)

pip3 install aiohttp

如果你想把chardetaiodnsbrotlipy一同安裝的話,可以使用以下命令安裝

pip3 install aiohttp[speedups]

快速開始

客戶端使用

簡單發送一個http請求

import aiohttp
import asyncio


async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get('http://python.org') as response:
            print('Status:', response.status)
            print('Content-type:', response.headers['content-type'])

            html = await response.text()
            print(f'Body: {html[:15]}...')


if __name__ == '__main__':
    asyncio.run(main())

結果如下

Status: 200
Content-type: text/html; charset=utf-8
Body: <!doctype html>...

服務端使用

簡單搭建一個web服務

from aiohttp import web


# 視圖函數
async def hello(request):
    name = request.match_info.get('name', 'Python')
    text = f'Hello, {name}'
    return web.Response(text=text)


app = web.Application()
app.add_routes([
    web.get('/', hello),
    web.get('/{name}', hello)
])  # 添加路由

if __name__ == '__main__':
    web.run_app(app, host='127.0.0.1')

一個簡單的服務就成功搭建了,在瀏覽器上訪問http://127.0.0.1:8080或者http://127.0.0.1:8080/name(name為你輸入的字符串)就可以看到對應的返回信息。

aiohttp客戶端的簡單應用

基本API的使用

aiohttp提供了一個簡單發送HTTP請求的協程方法:aiohttp.request()

基本API對於不需要持久連接,cookies和復雜的連接附件(如SSL證書)的HTTP請求來說是比較好用的,它的用法和python網絡請求requests包的用法差不多。

import aiohttp
import asyncio


async def get_html():
    async with aiohttp.request('GET', 'http://python.org/') as resp:
        print(resp.status)
        print(await resp.text())


if __name__ == '__main__':
    asyncio.run(get_html())

以上例子,aiohttp.request()中的第一個參數為method(HTTP方法),第二個參數為url(請求鏈接),其他比較重要的關鍵字參數還有headers(請求頭信息)、cookies(請求時攜帶的cookies)、params(原url組合的參數)、data(請求體的參數)等。

客戶端會話

客戶端會話(Client Session)是比較推薦使用的發起HTTP請求的接口。

會話(Session)封裝有一個連接池(連接池實例),默認支持持久連接。除非需要連接非常多不同的服務器,否則還是建議你在應用程序中只使用一個會話(Session),這樣有利於連接池。

import aiohttp
import asyncio


async def get_html(session, url):
    # 發送一個GET請求獲取頁面信息
    async with session.get(url) as resp:
        print(f'--- current url is {url} ---')
        print('Status:', resp.status)
        return await resp.text()


async def main():
    # 建立一個客戶端會話
    async with aiohttp.ClientSession() as session:
        html1 = await get_html(session, 'http://python.org')
        html2 = await get_html(session, 'https://baidu.com')
        print(html1)
        print(html2)


if __name__ == '__main__':
    asyncio.run(main())

通過aiohttp.ClientSession()創建一個客戶端會話session,session可以使用get和post等請求方法發送請求,相關參數也是類似requests包的傳參。

aiohttp異步爬蟲

我們來使用aiohttp實現一個簡單的爬蟲,爬取三張圖片

import time
import aiohttp
import asyncio


async def get_html(session, url):
    print('發送請求:', url)
    async with session.get(url) as response:
        content = await response.content.read()
        print('得到結果', url, len(content))
        filename = url.rsplit('/')[-1]
        print(f'正在下載{filename}...')
        with open(filename, 'wb') as file_object:
            file_object.write(content)
            print(f'{filename}下載成功')


async def main():
    async with aiohttp.ClientSession() as session:
        start_time = time.time()
        url_list = [
            'https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093544wallpaper1.jpg',
            'https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093557wallpaper2.jpg',
            'https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093613wallpaper3.jpg',
        ]
        tasks = [asyncio.create_task(get_html(session, url)) for url in url_list]
        await asyncio.wait(tasks)
        end_time = time.time()
        print(f'it cost {round(end_time - start_time, 4)}s.')


if __name__ == '__main__':
    asyncio.run(main())

執行結果如下

發送請求: https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093544wallpaper1.jpg
發送請求: https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093557wallpaper2.jpg
發送請求: https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093613wallpaper3.jpg
得到結果 https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093613wallpaper3.jpg 1215029
正在下載o_201106093613wallpaper3.jpg...
o_201106093613wallpaper3.jpg下載成功
得到結果 https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093544wallpaper1.jpg 1326652
正在下載o_201106093544wallpaper1.jpg...
o_201106093544wallpaper1.jpg下載成功
得到結果 https://images.cnblogs.com/cnblogs_com/blueberry-mint/1877253/o_201106093557wallpaper2.jpg 1867449
正在下載o_201106093557wallpaper2.jpg...
o_201106093557wallpaper2.jpg下載成功
it cost 0.1745s.

本例子中先創建一個客戶端會話session,在session使用asyncio.create_task()創建3個協程任務,然后通過asyncio.wait()掛起任務(異步執行)並獲取最終結果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM