網(wǎng)站首頁 編程語言 正文
Python?async+request與async+aiohttp實現(xiàn)異步網(wǎng)絡(luò)請求探索_python
作者:Light2077 ? 更新時間: 2022-12-01 編程語言前言
在學(xué)習(xí)協(xié)程的時候,會有一個疑問,使用協(xié)程語法進行異步請求時,比如async + requests
,會有用嗎?
其實細想一下就知道,由于requests庫是用同步的方式寫的,因此async + requests
是肯定沒用的。
但是本著實踐出真知的思想,順便復(fù)習(xí)鞏固一下多線程、async、aiohttp的寫法,還是手動來驗證一下。
為了規(guī)避網(wǎng)絡(luò)波動等影響,在本地用Flask搭建一個簡易的服務(wù)器用于測試。
先放結(jié)論:
-
threading + requests
能夠并發(fā)請求 -
async + requests
不能并發(fā)請求 -
async + aiohttp
能并發(fā)請求
因此在進行爬蟲的時候,要想加快效率,要么使用threading + requests
,要么就使用async + aiohttp
初始環(huán)境準(zhǔn)備
安裝測試所需要的庫
pip install flask
pip install requets
pip install aiohttp
在任意路徑創(chuàng)建一個文件夾(文件夾名隨意),例如./async_test
在該文件夾下創(chuàng)建一個空的py文件app.py
用于后續(xù)搭建測試用后端。
再創(chuàng)建3個py文件分別對應(yīng)3個實驗,創(chuàng)建完畢后文件目錄結(jié)構(gòu)如下(此時的py文件都是空的)
|- async_test
? |- app.py
? |- 1_threading_requests.py
? |- 2_async_requests.py
? |- 3_async_aiohttp.py
搭建測試用的后端
讓每次請求的時候先沉睡2秒,再返回結(jié)果,以此來模擬網(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
目錄下運行
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)
訪問 http://127.0.0.1:5000/ 延遲2秒后會看到Hello World!
完成這一步就搭建好了測試用后端
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
目錄下運行
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ā)請求的。
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
目錄下運行
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í)行的,異步并沒有起到效果
于是將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
目錄下運行
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í)行了,總耗時只有兩秒
說明python的協(xié)程語法需要配合異步python庫才會生效。
原文鏈接:https://blog.csdn.net/Light2077/article/details/127440915
相關(guān)推薦
- 2022-07-22 Python動態(tài)屬性有什么用
- 2022-07-15 C#使用BitConverter與BitArray類進行預(yù)定義基礎(chǔ)類型轉(zhuǎn)換_C#教程
- 2022-12-23 解讀pandas.DataFrame.corrwith_python
- 2022-06-21 Android?Studio實現(xiàn)下拉列表效果_Android
- 2022-05-17 解決使用maven打jar包缺失依賴包問題
- 2022-09-13 一文詳解C語言中文件相關(guān)函數(shù)的使用_C 語言
- 2022-05-06 Python判斷字符串中是否是中英文文小技巧
- 2022-04-11 springboot上傳文件到Nginx代理的FTP文件服務(wù)器
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支