非同步程式設計在 Python 開發中變得越來越重要。 隨著 asyncio
現在成為標準庫元件和許多相容的第三方包,這種範例將繼續存在。本教學課程示範如何使用 HTTPX
程式庫進行非同步 HTTP 請求 - 非阻塞程式碼的主要用例。
「非同步」、「非阻塞」和「並發」等術語可能會令人困惑。 本質上:
非同步程式碼避免阻塞,使其他程式碼能夠在等待結果時運作。 asyncio
函式庫為此提供了工具,並且 aiohttp
提供了專門的 HTTP 請求功能。 HTTP 請求非常適合非同步性,因為它們涉及等待伺服器回應,在此期間其他任務可以有效執行。
確保您的 Python 環境已配置。 如果需要,請參閱虛擬環境指南(需要 Python 3.7)。 安裝HTTPX
:
<code class="language-bash">pip install httpx==0.18.2</code>
此範例使用對 Pokémon API 的單一 GET 請求來取得 Mew(Pokémon #151)的資料:
<code class="language-python">import asyncio import httpx async def main(): url = 'https://pokeapi.co/api/v2/pokemon/151' async with httpx.AsyncClient() as client: response = await client.get(url) pokemon = response.json() print(pokemon['name']) asyncio.run(main())</code>
async
指定一個協程; await
產生對事件循環的控制,在結果可用時恢復執行。
當發出大量請求時,非同步性的真正力量是顯而易見的。此範例取得前 150 個 Pokémon 的資料:
<code class="language-python">import asyncio import httpx import time start_time = time.time() async def main(): async with httpx.AsyncClient() as client: for number in range(1, 151): url = f'https://pokeapi.co/api/v2/pokemon/{number}' response = await client.get(url) pokemon = response.json() print(pokemon['name']) asyncio.run(main()) print(f"--- {time.time() - start_time:.2f} seconds ---")</code>
執行的時間。 將此與同步方法進行比較。
同步等效項:
<code class="language-python">import httpx import time start_time = time.time() client = httpx.Client() for number in range(1, 151): url = f'https://pokeapi.co/api/v2/pokemon/{number}' response = client.get(url) pokemon = response.json() print(pokemon['name']) print(f"--- {time.time() - start_time:.2f} seconds ---")</code>
注意運行時差異。 HTTPX
的連接池最大限度地減少了差異,但 asyncio 提供了進一步的最佳化。
為了獲得卓越的效能,請使用 asyncio.ensure_future
和 asyncio.gather
同時執行請求:
<code class="language-python">import asyncio import httpx import time start_time = time.time() async def fetch_pokemon(client, url): response = await client.get(url) return response.json()['name'] async def main(): async with httpx.AsyncClient() as client: tasks = [asyncio.ensure_future(fetch_pokemon(client, f'https://pokeapi.co/api/v2/pokemon/{number}')) for number in range(1, 151)] pokemon_names = await asyncio.gather(*tasks) for name in pokemon_names: print(name) asyncio.run(main()) print(f"--- {time.time() - start_time:.2f} seconds ---")</code>
這透過並發運行請求顯著減少了執行時間。 總時間接近最長單次請求的持續時間。
使用 HTTPX
和非同步程式設計可以顯著提高多個 HTTP 請求的效能。本教學提供了 asyncio
的基本介紹;進一步探索其功能以增強您的 Python 專案。 考慮探索 aiohttp
來取代非同步 HTTP 請求處理。
以上是Python 中使用 HTTPX 和 asyncio 的非同步 HTTP 請求的詳細內容。更多資訊請關注PHP中文網其他相關文章!