python并發(fā)執(zhí)行request請求的示例
在Python中,我們可以使用requests
庫來發(fā)送HTTP請求,并使用threading
、multiprocessing
、asyncio
(配合aiohttp
)或concurrent.futures
等庫來并發(fā)執(zhí)行這些請求。這里,我將為我們展示使用concurrent.futures.ThreadPoolExecutor
和requests
庫并發(fā)執(zhí)行HTTP請求的示例。
1.使用concurrent.futures.ThreadPoolExecutor并發(fā)發(fā)送請求示例
首先,我們需要安裝requests
庫(如果還沒有安裝的話):
pip install requests
然后,我們可以使用以下代碼來并發(fā)地發(fā)送HTTP GET請求:
import concurrent.futures import requests # 假設我們有一個URL列表 urls = [ 'http://example.com/api/data1', 'http://example.com/api/data2', 'http://example.com/api/data3', # ... 添加更多URL ] # 定義一個函數(shù),該函數(shù)接收一個URL,發(fā)送GET請求,并打印響應內(nèi)容 def fetch_data(url): try: response = requests.get(url) response.raise_for_status() # 如果請求失?。ɡ?,4xx、5xx),則拋出HTTPError異常 print(f"URL: {url}, Status Code: {response.status_code}, Content: {response.text[:100]}...") except requests.RequestException as e: print(f"Error fetching {url}: {e}") # 使用ThreadPoolExecutor并發(fā)地執(zhí)行fetch_data函數(shù) with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: # 你可以根據(jù)需要調(diào)整max_workers的值 future_to_url = {executor.submit(fetch_data, url): url for url in urls} for future in concurrent.futures.as_completed(future_to_url): url = future_to_url[future] try: # 通過調(diào)用future.result()來獲取函數(shù)的返回值,這會阻塞,直到結(jié)果可用 # 但是請注意,這里我們只是打印結(jié)果,沒有返回值,所以調(diào)用future.result()只是為了等待函數(shù)完成 future.result() except Exception as exc: print(f'Generated an exception for {url}: {exc}')
在這里簡單解釋一下這個代碼示例。
(1)我們首先定義了一個URL列表,這些是我們想要并發(fā)訪問的URL。
(2)然后,我們定義了一個函數(shù)fetch_data
,它接收一個URL作為參數(shù),發(fā)送GET請求,并打印響應的狀態(tài)碼和內(nèi)容(只打印前100個字符以節(jié)省空間)。如果發(fā)生任何請求異常(例如,網(wǎng)絡錯誤、無效的URL、服務器錯誤等),它會捕獲這些異常并打印錯誤消息。
(3)使用concurrent.futures.ThreadPoolExecutor
,我們可以輕松地并發(fā)執(zhí)行fetch_data
函數(shù)。我們創(chuàng)建了一個ThreadPoolExecutor
實例,并指定了最大工作線程數(shù)(在這個例子中是5,但我們可以根據(jù)需要調(diào)整這個值)。然后,我們使用列表推導式將每個URL與一個Future
對象關(guān)聯(lián)起來,該對象表示異步執(zhí)行的函數(shù)。
(4)最后,我們使用as_completed
函數(shù)迭代所有完成的Future
對象。對于每個完成的Future
對象,我們調(diào)用result
方法來獲取函數(shù)的返回值(盡管在這個例子中我們沒有使用返回值)。如果函數(shù)執(zhí)行期間發(fā)生任何異常,result
方法會重新引發(fā)該異常,我們可以捕獲并處理它。
這個示例展示了如何使用Python的concurrent.futures
模塊來并發(fā)地發(fā)送HTTP請求。這種方法在IO密集型任務(如網(wǎng)絡請求)上特別有效,因為它允許在等待IO操作完成時釋放CPU資源供其他線程使用。
2.requests庫并發(fā)發(fā)送HTTP GET請求的完整Python代碼示例
以下是一個使用concurrent.futures.ThreadPoolExecutor
和requests
庫并發(fā)發(fā)送HTTP GET請求的完整Python代碼示例:
import concurrent.futures import requests # 假設我們有一個URL列表 urls = [ 'https://www.example.com', 'https://httpbin.org/get', 'https://api.example.com/some/endpoint', # ... 添加更多URL ] # 定義一個函數(shù)來發(fā)送GET請求并處理響應 def fetch_url(url): try: response = requests.get(url, timeout=5) # 設置超時為5秒 response.raise_for_status() # 如果請求失敗,拋出HTTPError異常 return response.text # 返回響應內(nèi)容,這里只是作為示例,實際使用中可能不需要返回 except requests.RequestException as e: print(f"Error fetching {url}: {e}") return None # 使用ThreadPoolExecutor并發(fā)地發(fā)送請求 def fetch_all_urls(urls): with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: # 使用executor.map來自動處理迭代和Future的獲取 results = executor.map(fetch_url, urls) # 處理結(jié)果(這里只是簡單地打印出來) for result in results: if result is not None: print(f"Fetched content from a URL (truncated): {result[:100]}...") # 調(diào)用函數(shù) fetch_all_urls(urls)
在這個示例中,我們定義了一個fetch_url
函數(shù),它接收一個URL,發(fā)送GET請求,并返回響應內(nèi)容(或在出錯時返回None
)。然后,我們定義了一個fetch_all_urls
函數(shù),它使用ThreadPoolExecutor
并發(fā)地調(diào)用fetch_url
函數(shù),并將結(jié)果收集在一個迭代器中。最后,我們遍歷這個迭代器,并打印出每個成功獲取到的響應內(nèi)容(這里只打印了前100個字符作為示例)。
請注意,我們在requests.get
中設置了一個超時參數(shù)(timeout=5
),這是為了防止某個請求因為網(wǎng)絡問題或其他原因而無限期地等待。在實際應用中,根據(jù)我們的需求調(diào)整這個值是很重要的。
此外,我們還使用了executor.map
來自動處理迭代和Future
的獲取。executor.map
函數(shù)會返回一個迭代器,它會產(chǎn)生fetch_url
函數(shù)的返回值,這些值在函數(shù)完成后會自動從相應的Future
對象中提取出來。這使得代碼更加簡潔,并且減少了顯式處理Future
對象的需要。
3.如何在Python中實現(xiàn)并發(fā)編程
在Python中實現(xiàn)并發(fā)編程,主要有以下幾種方式:
(1)使用threading
模塊threading
模塊提供了多線程編程的API。Python的線程是全局解釋器鎖(GIL)下的線程,這意味著在任意時刻只有一個線程能夠執(zhí)行Python字節(jié)碼。然而,對于I/O密集型任務(如網(wǎng)絡請求),多線程仍然可以通過并發(fā)地等待I/O操作來提高性能。
示例:
import threading import requests def fetch_url(url): try: response = requests.get(url) response.raise_for_status() print(f"URL: {url}, Status Code: {response.status_code}") except requests.RequestException as e: print(f"Error fetching {url}: {e}") threads = [] for url in urls: t = threading.Thread(target=fetch_url, args=(url,)) threads.append(t) t.start() # 等待所有線程完成 for t in threads: t.join()
(2)使用multiprocessing
模塊multiprocessing
模塊提供了跨多個Python解釋器的進程間并行處理。這對于CPU密集型任務特別有用,因為每個進程都有自己的Python解釋器和GIL,可以充分利用多核CPU的并行處理能力。
示例:
from multiprocessing import Pool import requests def fetch_url(url): try: response = requests.get(url) response.raise_for_status() return f"URL: {url}, Status Code: {response.status_code}" except requests.RequestException as e: return f"Error fetching {url}: {e}" with Pool(processes=4) as pool: # 設定進程池的大小 results = pool.map(fetch_url, urls) for result in results: print(result)
(3)使用asyncio
模塊(針對異步I/O)asyncio
是Python 3.4+中引入的用于編寫單線程并發(fā)代碼的庫,特別適合編寫網(wǎng)絡客戶端和服務器。它使用協(xié)程(coroutine)和事件循環(huán)(event loop)來管理并發(fā)。
示例(使用aiohttp
庫進行異步HTTP請求):
import asyncio import aiohttp async def fetch_url(url, session): async with session.get(url) as response: return await response.text() async def main(): async with aiohttp.ClientSession() as session: tasks = [] for url in urls: task = asyncio.create_task(fetch_url(url, session)) tasks.append(task) results = await asyncio.gather(*tasks) for result, url in zip(results, urls): print(f"URL: {url}, Content: {result[:100]}...") # Python 3.7+ 可以使用下面的方式運行主協(xié)程 asyncio.run(main())
注意:asyncio.run()
是在Python 3.7中引入的,用于運行頂層入口點函數(shù)。在Python 3.6及以下版本中,我們需要自己設置和運行事件循環(huán)。
(4)使用concurrent.futures
模塊concurrent.futures
模塊提供了高層次的接口,可以輕松地編寫并發(fā)代碼。它提供了ThreadPoolExecutor
(用于線程池)和ProcessPoolExecutor
(用于進程池)。
前面已經(jīng)給出了ThreadPoolExecutor
的示例,這里不再重復。ProcessPoolExecutor
的用法與ThreadPoolExecutor
類似,只是它是基于進程的。
選擇哪種并發(fā)方式取決于我們的具體需求。對于I/O密集型任務,多線程或異步I/O通常是更好的選擇;對于CPU密集型任務,多進程可能是更好的選擇。此外,異步I/O通常比多線程具有更好的性能,特別是在高并發(fā)的網(wǎng)絡應用中。
到此這篇關(guān)于python并發(fā)執(zhí)行request請求的文章就介紹到這了,更多相關(guān)python request請求內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Keras自定義實現(xiàn)帶masking的meanpooling層方式
這篇文章主要介紹了Keras自定義實現(xiàn)帶masking的meanpooling層方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06pycharm 創(chuàng)建py文件總是為txt格式的問題及解決
這篇文章主要介紹了pycharm 創(chuàng)建py文件總是為txt格式的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07詳解pandas中MultiIndex和對象實際索引不一致問題
這篇文章主要介紹了詳解pandas中MultiIndex和對象實際索引不一致問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07Pandas數(shù)據(jù)清洗和預處理的實現(xiàn)示例
本文主要介紹了Pandas數(shù)據(jù)清洗和預處理的實現(xiàn)示例,包括處理缺失值、異常值,進行數(shù)據(jù)轉(zhuǎn)換和規(guī)范化,以及處理重復數(shù)據(jù)等操作,感興趣的可以了解一下2024-01-01Python讀寫及備份oracle數(shù)據(jù)庫操作示例
這篇文章主要介紹了Python讀寫及備份oracle數(shù)據(jù)庫操作,結(jié)合實例形式分析了Python針對Oracle數(shù)據(jù)庫操作的相關(guān)庫安裝,以及使用cx_Oracle與pandas庫進行Oracle數(shù)據(jù)庫的查詢、插入、備份等操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2018-05-05