python并發(fā)執(zhí)行request請(qǐng)求的示例
在Python中,我們可以使用requests庫(kù)來(lái)發(fā)送HTTP請(qǐng)求,并使用threading、multiprocessing、asyncio(配合aiohttp)或concurrent.futures等庫(kù)來(lái)并發(fā)執(zhí)行這些請(qǐng)求。這里,我將為我們展示使用concurrent.futures.ThreadPoolExecutor和requests庫(kù)并發(fā)執(zhí)行HTTP請(qǐng)求的示例。
1.使用concurrent.futures.ThreadPoolExecutor并發(fā)發(fā)送請(qǐng)求示例
首先,我們需要安裝requests庫(kù)(如果還沒(méi)有安裝的話(huà)):
pip install requests
然后,我們可以使用以下代碼來(lái)并發(fā)地發(fā)送HTTP GET請(qǐng)求:
import concurrent.futures
import requests
# 假設(shè)我們有一個(gè)URL列表
urls = [
'http://example.com/api/data1',
'http://example.com/api/data2',
'http://example.com/api/data3',
# ... 添加更多URL
]
# 定義一個(gè)函數(shù),該函數(shù)接收一個(gè)URL,發(fā)送GET請(qǐng)求,并打印響應(yīng)內(nèi)容
def fetch_data(url):
try:
response = requests.get(url)
response.raise_for_status() # 如果請(qǐng)求失?。ɡ?,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:
# 通過(guò)調(diào)用future.result()來(lái)獲取函數(shù)的返回值,這會(huì)阻塞,直到結(jié)果可用
# 但是請(qǐng)注意,這里我們只是打印結(jié)果,沒(méi)有返回值,所以調(diào)用future.result()只是為了等待函數(shù)完成
future.result()
except Exception as exc:
print(f'Generated an exception for {url}: {exc}')在這里簡(jiǎn)單解釋一下這個(gè)代碼示例。
(1)我們首先定義了一個(gè)URL列表,這些是我們想要并發(fā)訪(fǎng)問(wèn)的URL。
(2)然后,我們定義了一個(gè)函數(shù)fetch_data,它接收一個(gè)URL作為參數(shù),發(fā)送GET請(qǐng)求,并打印響應(yīng)的狀態(tài)碼和內(nèi)容(只打印前100個(gè)字符以節(jié)省空間)。如果發(fā)生任何請(qǐng)求異常(例如,網(wǎng)絡(luò)錯(cuò)誤、無(wú)效的URL、服務(wù)器錯(cuò)誤等),它會(huì)捕獲這些異常并打印錯(cuò)誤消息。
(3)使用concurrent.futures.ThreadPoolExecutor,我們可以輕松地并發(fā)執(zhí)行fetch_data函數(shù)。我們創(chuàng)建了一個(gè)ThreadPoolExecutor實(shí)例,并指定了最大工作線(xiàn)程數(shù)(在這個(gè)例子中是5,但我們可以根據(jù)需要調(diào)整這個(gè)值)。然后,我們使用列表推導(dǎo)式將每個(gè)URL與一個(gè)Future對(duì)象關(guān)聯(lián)起來(lái),該對(duì)象表示異步執(zhí)行的函數(shù)。
(4)最后,我們使用as_completed函數(shù)迭代所有完成的Future對(duì)象。對(duì)于每個(gè)完成的Future對(duì)象,我們調(diào)用result方法來(lái)獲取函數(shù)的返回值(盡管在這個(gè)例子中我們沒(méi)有使用返回值)。如果函數(shù)執(zhí)行期間發(fā)生任何異常,result方法會(huì)重新引發(fā)該異常,我們可以捕獲并處理它。
這個(gè)示例展示了如何使用Python的concurrent.futures模塊來(lái)并發(fā)地發(fā)送HTTP請(qǐng)求。這種方法在IO密集型任務(wù)(如網(wǎng)絡(luò)請(qǐng)求)上特別有效,因?yàn)樗试S在等待IO操作完成時(shí)釋放CPU資源供其他線(xiàn)程使用。
2.requests庫(kù)并發(fā)發(fā)送HTTP GET請(qǐng)求的完整Python代碼示例
以下是一個(gè)使用concurrent.futures.ThreadPoolExecutor和requests庫(kù)并發(fā)發(fā)送HTTP GET請(qǐng)求的完整Python代碼示例:
import concurrent.futures
import requests
# 假設(shè)我們有一個(gè)URL列表
urls = [
'https://www.example.com',
'https://httpbin.org/get',
'https://api.example.com/some/endpoint',
# ... 添加更多URL
]
# 定義一個(gè)函數(shù)來(lái)發(fā)送GET請(qǐng)求并處理響應(yīng)
def fetch_url(url):
try:
response = requests.get(url, timeout=5) # 設(shè)置超時(shí)為5秒
response.raise_for_status() # 如果請(qǐng)求失敗,拋出HTTPError異常
return response.text # 返回響應(yīng)內(nèi)容,這里只是作為示例,實(shí)際使用中可能不需要返回
except requests.RequestException as e:
print(f"Error fetching {url}: {e}")
return None
# 使用ThreadPoolExecutor并發(fā)地發(fā)送請(qǐng)求
def fetch_all_urls(urls):
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
# 使用executor.map來(lái)自動(dòng)處理迭代和Future的獲取
results = executor.map(fetch_url, urls)
# 處理結(jié)果(這里只是簡(jiǎn)單地打印出來(lái))
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)在這個(gè)示例中,我們定義了一個(gè)fetch_url函數(shù),它接收一個(gè)URL,發(fā)送GET請(qǐng)求,并返回響應(yīng)內(nèi)容(或在出錯(cuò)時(shí)返回None)。然后,我們定義了一個(gè)fetch_all_urls函數(shù),它使用ThreadPoolExecutor并發(fā)地調(diào)用fetch_url函數(shù),并將結(jié)果收集在一個(gè)迭代器中。最后,我們遍歷這個(gè)迭代器,并打印出每個(gè)成功獲取到的響應(yīng)內(nèi)容(這里只打印了前100個(gè)字符作為示例)。
請(qǐng)注意,我們?cè)?code>requests.get中設(shè)置了一個(gè)超時(shí)參數(shù)(timeout=5),這是為了防止某個(gè)請(qǐng)求因?yàn)榫W(wǎng)絡(luò)問(wèn)題或其他原因而無(wú)限期地等待。在實(shí)際應(yīng)用中,根據(jù)我們的需求調(diào)整這個(gè)值是很重要的。
此外,我們還使用了executor.map來(lái)自動(dòng)處理迭代和Future的獲取。executor.map函數(shù)會(huì)返回一個(gè)迭代器,它會(huì)產(chǎn)生fetch_url函數(shù)的返回值,這些值在函數(shù)完成后會(huì)自動(dòng)從相應(yīng)的Future對(duì)象中提取出來(lái)。這使得代碼更加簡(jiǎn)潔,并且減少了顯式處理Future對(duì)象的需要。
3.如何在Python中實(shí)現(xiàn)并發(fā)編程
在Python中實(shí)現(xiàn)并發(fā)編程,主要有以下幾種方式:
(1)使用threading模塊threading模塊提供了多線(xiàn)程編程的API。Python的線(xiàn)程是全局解釋器鎖(GIL)下的線(xiàn)程,這意味著在任意時(shí)刻只有一個(gè)線(xiàn)程能夠執(zhí)行Python字節(jié)碼。然而,對(duì)于I/O密集型任務(wù)(如網(wǎng)絡(luò)請(qǐng)求),多線(xiàn)程仍然可以通過(guò)并發(fā)地等待I/O操作來(lái)提高性能。
示例:
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()
# 等待所有線(xiàn)程完成
for t in threads:
t.join()(2)使用multiprocessing模塊multiprocessing模塊提供了跨多個(gè)Python解釋器的進(jìn)程間并行處理。這對(duì)于CPU密集型任務(wù)特別有用,因?yàn)槊總€(gè)進(jìn)程都有自己的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: # 設(shè)定進(jìn)程池的大小
results = pool.map(fetch_url, urls)
for result in results:
print(result)(3)使用asyncio模塊(針對(duì)異步I/O)asyncio是Python 3.4+中引入的用于編寫(xiě)單線(xiàn)程并發(fā)代碼的庫(kù),特別適合編寫(xiě)網(wǎng)絡(luò)客戶(hù)端和服務(wù)器。它使用協(xié)程(coroutine)和事件循環(huán)(event loop)來(lái)管理并發(fā)。
示例(使用aiohttp庫(kù)進(jìn)行異步HTTP請(qǐng)求):
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+ 可以使用下面的方式運(yùn)行主協(xié)程
asyncio.run(main())注意:asyncio.run()是在Python 3.7中引入的,用于運(yùn)行頂層入口點(diǎn)函數(shù)。在Python 3.6及以下版本中,我們需要自己設(shè)置和運(yùn)行事件循環(huán)。
(4)使用concurrent.futures模塊concurrent.futures模塊提供了高層次的接口,可以輕松地編寫(xiě)并發(fā)代碼。它提供了ThreadPoolExecutor(用于線(xiàn)程池)和ProcessPoolExecutor(用于進(jìn)程池)。
前面已經(jīng)給出了ThreadPoolExecutor的示例,這里不再重復(fù)。ProcessPoolExecutor的用法與ThreadPoolExecutor類(lèi)似,只是它是基于進(jìn)程的。
選擇哪種并發(fā)方式取決于我們的具體需求。對(duì)于I/O密集型任務(wù),多線(xiàn)程或異步I/O通常是更好的選擇;對(duì)于CPU密集型任務(wù),多進(jìn)程可能是更好的選擇。此外,異步I/O通常比多線(xiàn)程具有更好的性能,特別是在高并發(fā)的網(wǎng)絡(luò)應(yīng)用中。
到此這篇關(guān)于python并發(fā)執(zhí)行request請(qǐng)求的文章就介紹到這了,更多相關(guān)python request請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Python中的if __name__ == __main__詳情
在學(xué)習(xí)Python的過(guò)程中發(fā)現(xiàn)即使把if __name__ == ‘__main__’ 去掉,程序還是照樣運(yùn)行。很多小伙伴只知道是這么用的,也沒(méi)有深究具體的作用。這篇文字就來(lái)介紹一下Python中的if __name__ == ‘__main__’的作用,需要的朋友參考下文2021-09-09
Python入門(mén)教程(三十八)Python的NumPy庫(kù)簡(jiǎn)介
這篇文章主要介紹了Python入門(mén)教程(三十八)Python的NumPy庫(kù)簡(jiǎn)介,NumPy 是用于處理數(shù)組的 python 庫(kù),它還擁有在線(xiàn)性代數(shù)、傅立葉變換和矩陣領(lǐng)域中工作的函數(shù),需要的朋友可以參考下2023-05-05
Python中import導(dǎo)入不同目錄的模塊方法詳解
這篇文章主要介紹了Python中import導(dǎo)入不同目錄的模塊方法詳解,需要的朋友可以參考下2020-02-02
Python類(lèi)型標(biāo)注里Optional的實(shí)現(xiàn)
本文主要介紹了Python類(lèi)型標(biāo)注里Optional的實(shí)現(xiàn),包括與默認(rèn)參數(shù)/可選參數(shù)的關(guān)系,以及在靜態(tài)類(lèi)型檢查中的注意事項(xiàng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2026-02-02
PyTorch 分布式訓(xùn)練的實(shí)現(xiàn)
本文主要介紹了PyTorch 分布式訓(xùn)練的實(shí)現(xiàn),包括數(shù)據(jù)并行、模型并行、混合并行和流水線(xiàn)并行等模式,感興趣的可以了解一下2025-05-05
urllib和BeautifulSoup爬取維基百科的詞條簡(jiǎn)單實(shí)例
這篇文章主要介紹了urllib和BeautifulSoup爬取維基百科的詞條簡(jiǎn)單實(shí)例,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
python3的UnicodeDecodeError解決方法
這篇文章主要介紹了python3的UnicodeDecodeError解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
Python 中 AttributeError: ‘NoneType‘ obje
Python “AttributeError: ‘NoneType’ object has no attribute” 發(fā)生在我們嘗試訪(fǎng)問(wèn) None 值的屬性時(shí),例如 來(lái)自不返回任何內(nèi)容的函數(shù)的賦值, 要解決該錯(cuò)誤,請(qǐng)?jiān)谠L(fǎng)問(wèn)屬性之前更正分配,本文通過(guò)示例給大家說(shuō)明錯(cuò)誤是如何發(fā)生的,感興趣的朋友一起看看吧2023-08-08
Python使用SocketServer模塊編寫(xiě)基本服務(wù)器程序的教程
SocketServer模塊中集成了實(shí)現(xiàn)socket通信服務(wù)器功能所需的各種類(lèi)和方法,這里我們就來(lái)看一下Python使用SocketServer模塊編寫(xiě)基本服務(wù)器程序的教程:2016-07-07

