Python?async+request與async+aiohttp實(shí)現(xiàn)異步網(wǎng)絡(luò)請(qǐng)求探索
前言
在學(xué)習(xí)協(xié)程的時(shí)候,會(huì)有一個(gè)疑問(wèn),使用協(xié)程語(yǔ)法進(jìn)行異步請(qǐng)求時(shí),比如async + requests,會(huì)有用嗎?
其實(shí)細(xì)想一下就知道,由于requests庫(kù)是用同步的方式寫的,因此async + requests是肯定沒(méi)用的。
但是本著實(shí)踐出真知的思想,順便復(fù)習(xí)鞏固一下多線程、async、aiohttp的寫法,還是手動(dòng)來(lái)驗(yàn)證一下。
為了規(guī)避網(wǎng)絡(luò)波動(dòng)等影響,在本地用Flask搭建一個(gè)簡(jiǎn)易的服務(wù)器用于測(cè)試。
先放結(jié)論:
threading + requests能夠并發(fā)請(qǐng)求async + requests不能并發(fā)請(qǐng)求async + aiohttp能并發(fā)請(qǐng)求
因此在進(jìn)行爬蟲的時(shí)候,要想加快效率,要么使用threading + requests ,要么就使用async + aiohttp
初始環(huán)境準(zhǔn)備
安裝測(cè)試所需要的庫(kù)
pip install flask
pip install requets
pip install aiohttp
在任意路徑創(chuàng)建一個(gè)文件夾(文件夾名隨意),例如./async_test
在該文件夾下創(chuàng)建一個(gè)空的py文件app.py用于后續(xù)搭建測(cè)試用后端。
再創(chuàng)建3個(gè)py文件分別對(duì)應(yīng)3個(gè)實(shí)驗(yàn),創(chuàng)建完畢后文件目錄結(jié)構(gòu)如下(此時(shí)的py文件都是空的)
|- async_test
|- app.py
|- 1_threading_requests.py
|- 2_async_requests.py
|- 3_async_aiohttp.py
搭建測(cè)試用的后端
讓每次請(qǐng)求的時(shí)候先沉睡2秒,再返回結(jié)果,以此來(lái)模擬網(wǎng)絡(luò)延遲。
在app.py文件中添加如下代碼
## app.py ##
from flask import Flask
import time
app = Flask(__name__)
@app.route("/")
def index():
time.sleep(2)
return "Hello World!"
if __name__ == '__main__':
app.run()在./async_test目錄下運(yùn)行
python app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
訪問(wèn) http://127.0.0.1:5000/ 延遲2秒后會(huì)看到Hello World!
完成這一步就搭建好了測(cè)試用后端
1.threading requests
在1_threading_requests.py文件中添加如下代碼
## 1_threading_requests.py ##
import time
import threading
import requests
def get(i):
print(time.strftime('%X'), 'start', i)
resp = requests.get('http://127.0.0.1:5000/')
print(time.strftime('%X'), 'end', i)
start = time.perf_counter()
for i in range(4):
threading.Thread(target=get, args=(i,)).start()
print(f'total {time.perf_counter() - start:.2f}s ')在./async_test目錄下運(yùn)行
python 1_threading_requests.py
09:23:19 start 0
09:23:19 start 1
09:23:19 start 2
09:23:19 start 3
09:23:21 end 2
09:23:21 end 0
09:23:21 end 3
09:23:21 end 1
發(fā)現(xiàn)使用多線程的寫法是能夠并發(fā)請(qǐng)求的。
2.async requests
在2_async_requests.py文件中添加如下代碼
## 2_async_requests.py ##
import time
import asyncio
import requests
async def get(i):
print(time.strftime('%X'), 'start', i)
resp = requests.get('http://127.0.0.1:5000/')
print(time.strftime('%X'), 'end', i)
async def main():
for i in range(4):
asyncio.create_task(get(i))
asyncio.run(main())在./async_test目錄下運(yùn)行
python 2_async_requests.py
09:27:11 start 0
09:27:13 end 0
09:27:13 start 1
09:27:15 end 1
09:27:15 start 2
09:27:17 end 2
09:27:17 start 3
09:27:19 end 3
發(fā)現(xiàn)async+requests的寫法,代碼是順序執(zhí)行的,異步并沒(méi)有起到效果
于是將get(i)函數(shù)用aiohttp重寫
3.async aiohttp
在3_async_aiohttp.py文件中添加如下代碼
## 3_async_aiohttp.py ##
import time
import asyncio
import aiohttp
import requests
async def get(i):
print(time.strftime('%X'), 'start', i)
async with aiohttp.ClientSession() as session:
async with session.get('http://127.0.0.1:5000/') as response:
html = await response.text()
print(time.strftime('%X'), 'end', i)
async def main():
tasks = [asyncio.create_task(get(i)) for i in range(4)]
await asyncio.gather(*tasks)
asyncio.run(main())在./async_test目錄下運(yùn)行
python 3_async_aiohttp.py
09:37:43 start 0
09:37:43 start 1
09:37:43 start 2
09:37:43 start 3
09:37:45 end 0
09:37:45 end 2
09:37:45 end 3
09:37:45 end 1
發(fā)現(xiàn)代碼成功異步執(zhí)行了,總耗時(shí)只有兩秒
說(shuō)明python的協(xié)程語(yǔ)法需要配合異步python庫(kù)才會(huì)生效。
到此這篇關(guān)于Python async+request與async+aiohttp實(shí)現(xiàn)異步網(wǎng)絡(luò)請(qǐng)求探索的文章就介紹到這了,更多相關(guān)Python異步網(wǎng)絡(luò)請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中使用Celery容聯(lián)云異步發(fā)送驗(yàn)證碼功能
Celery 是一個(gè) 基于python開(kāi)發(fā)的分布式異步消息任務(wù)隊(duì)列,通過(guò)它可以輕松的實(shí)現(xiàn)任務(wù)的異步處理,本文重點(diǎn)給大家介紹使用Celery容聯(lián)云異步發(fā)送驗(yàn)證碼功能,感興趣的朋友一起看看吧2021-09-09
三種Matplotlib中動(dòng)態(tài)更新繪圖的方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了如何隨著數(shù)據(jù)的變化動(dòng)態(tài)更新Matplotlib(Python的數(shù)據(jù)可視化庫(kù))圖,文中介紹了常用的三種方法,希望對(duì)大家有所幫助2024-04-04
十行Python代碼實(shí)現(xiàn)文字識(shí)別功能
這篇文章主要和大家分享如何調(diào)用百度的接口實(shí)現(xiàn)圖片的文字識(shí)別。整體是用Python實(shí)現(xiàn),所需要使用的第三方庫(kù)包括aip、PIL、keyboard、pyinstaller,需要的可以參考一下2022-05-05
PyTorch一小時(shí)掌握之神經(jīng)網(wǎng)絡(luò)氣溫預(yù)測(cè)篇
這篇文章主要介紹了PyTorch一小時(shí)掌握之神經(jīng)網(wǎng)絡(luò)氣溫預(yù)測(cè)篇,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
python在windows和linux下獲得本機(jī)本地ip地址方法小結(jié)
這篇文章主要介紹了python在windows和linux下獲得本機(jī)本地ip地址方法,實(shí)例分析了Python獲得IP地址的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
python進(jìn)階從青銅到王者一定會(huì)用上的Python技巧
這篇文章主要介紹了python進(jìn)階從青銅到王者一定會(huì)用上的Python技巧,本文通過(guò)幾個(gè)Python的小案例,讓大家體會(huì)其中蘊(yùn)含的技巧一起來(lái)圍觀吧2021-09-09

