在處理與資料預處理和網路開發相關的應用程式時,需要執行多個 HTTP 請求。在處理大量請求的情況下,使用同步請求往往效率比較低,因為每個請求都必須等待前一個請求完成。因此,這種方法會顯著延遲,尤其是當向具有不同響應時間的外部 API 發出請求時效率更低。與同步請求不同,非同步請求允許我們可以同時發出多個請求,這非常高效且執行速度更快。
在本文中,我們將瞭解如何使用 Python 發出非同步 HTTP 請求。我們將使用專為 Python 中的非同步操作而設計的 “aiohttp” 庫。
使用 Python 的非同步請求
先決條件
首先,讓我們瞭解一下在深入研究 Asynchronous 請求之前我們應該熟悉的一些先決條件:
Python 程式語言基礎知識
基本瞭解 HTTP 請求和 Python 庫請求
熟悉 Python 中的非同步程式設計概念,例如 “async” 和 “await”
首先安裝庫 “aiohttp” 和 “asyncio”。如果作業系統是 Windows,請使用 “pip”,如果作業系統是 Mac/Linux,請使用 “pip3”。
pip/pip3 install aiohttp asyncio
使用 aiohttp 進行非同步請求
儘管 “requests” 庫非常適合同步發出 HTTP 請求,但它不支援非同步操作。因此,對於非同步請求,使用 aiohttp 是 Python 中用於發出非同步請求的庫,因為它提供了一個易於使用的 API 來發出非同步 HTTP 請求,使我們能夠利用非阻塞操作。
與同步 “requests” 庫不同,“aiohttp” 庫專為非同步操作而設計,該庫的核心元件之一是 ClientSession。
什麼是 aiohttp 中的 ClinetSession?
在“aiohttp”庫中,核心元件“ClientSession”基本上就是一個物件,它有效地管理和重用 HTTP 連線,也減少了為每個請求建立和關閉連線的開銷。此外,我們還可以使用 “ClientSession” 來發出請求,例如 GET 或 POST,這絕對可以確保會話在多個請求中保持活動狀態,從而提高效能。
以下是 “ClientSession” 的工作原理步驟:
1. 建立會話:首先,首先建立 ClientSession 的例項,用於管理連線池。這基本上允許為多個請求重用連線。
2. 發出請求:在第二步中,在 session 本身中,我們可以使用 session.get、session.post 等方式發出非同步請求。這些請求的執行通常不會阻塞我們程式的流程。
3. 關閉會話:在最後一步中,完成上一步後,將關閉會話以釋放資源。使用 “async with” 可確保會話在使用後得到正確清理。
程式碼實現示例
現在,讓我們考慮一個真實的例子,其中需要同時從多個 API 獲取資料。以下是演示如何使用 “aiohttp” 執行此操作的程式碼
import aiohttp import asyncio import time async def fetch_data(session, url): print(f"Starting task: {url}") async with session.get(url) as response: await asyncio.sleep(1) # Simulating a delay data = await response.json() print(f"Completed task: {url}") return data async def main(): urls = [ 'https://api.github.com', 'https://api.spacexdata.com/v4/launches/latest', 'https://jsonplaceholder.typicode.com/todos/1' ] async with aiohttp.ClientSession() as session: tasks = [fetch_data(session, url) for url in urls] results = await asyncio.gather(*tasks) for result in results: print(result) if __name__ == '__main__': start_time = time.time() asyncio.run(main()) print(f"Total time taken: {time.time() - start_time} seconds")
輸出:
使用 Python AioHttp 發出非同步請求
上面的程式碼示例向 3 個不同的 API 發出非同步請求,然後列印 JSON 響應。使用 “asyncio.gather” 可確保所有請求同時執行,並顯著減少整體執行時間。
錯誤處理
爲了確保應用程式的健壯性,非同步程式碼中的 Hande 錯誤非常重要。在 “aiohttp” 庫中,可以透過在非同步函式中使用 “try-except” 塊來找到錯誤。下面是一個示例:
async def fetch_data(session, url): print(f"Starting task: {url}") try: async with session.get(url) as response: response.raise_for_status() # Raise exception for HTTP errors await asyncio.sleep(1) # Simulating a delay data = await response.json() print(f"Completed task: {url}") return data except aiohttp.ClientError as e: print(f"Error fetching data from {url}: {e}") except asyncio.TimeoutError: print(f"Request to {url} timed out")
在上面的錯誤處理程式碼示例中,“fetch_data”包括對“aiohttp.ClientError“和”asyncio.TimeoutError 的將記錄錯誤,並且 python 程式將繼續執行其他任務。
結論
非同步請求是提高 Python 應用程式效能的一種非常強大且非常強大的方法,尤其是在我們處理多個外部 API 呼叫的情況下。透過使用 aiohttp python 庫,我們可以輕鬆實現非阻塞的 HTTP 請求,從而顯著減少執行時間。透過有效處理錯誤,非同步程式碼的健壯性得到了進一步增強。透過遵循本文中討論的上述步驟,我們將輕鬆地在專案中實現非同步請求,以提高效能和效率。