糧食局網(wǎng)站建設報告網(wǎng)紅推廣
出現(xiàn)錯誤“ConnectionError: Max retries exceeded with url”有多種原因:
- 向
request.get()
方法傳遞了不正確或不完整的 URL。 - 我們正受到 API 的速率限制。
- requests 無法驗證您向其發(fā)出請求的網(wǎng)站的 SSL 證書。
確保我們指定了正確且完整的 URL 和路徑。
# ?? 未指定協(xié)議 (https://)
example.com/posts# ? 完整網(wǎng)址的示例
https://example.com/posts
仔細檢查我們沒有在 URL 和路徑中輸入任何錯誤。
使用 Retry 對象進行回退重試
解決該錯誤的一種方法是使用 Retry
對象并指定要重試多少次與連接相關的錯誤,并設置在兩次嘗試之間應用的退避因子。
import requests
from requests.adapters import HTTPAdapter, Retrydef make_request():session = requests.Session()retry = Retry(connect=3, backoff_factor=0.5)adapter = HTTPAdapter(max_retries=retry)session.mount('http://', adapter)session.mount('https://', adapter)url = 'https://example.com/api/users'response = session.get(url)parsed = response.json()print(parsed)make_request()
Session 對象允許我們跨請求保留某些參數(shù)。
我們將以下關鍵字參數(shù)傳遞給 Retry 對象:
- connect - 要重試的與連接相關的錯誤數(shù)
- backoff_factor - 第二次嘗試后在兩次嘗試之間應用的退避因子。
上面的示例在第二次嘗試后以 0.5 秒的退避因子重試請求 3 次。
使用 try/except 語句在發(fā)生錯誤時不重試
如果不想在發(fā)生錯誤時重試,也可以使用 try/except
塊。
import requestsdef make_request():try:url = 'https://example.com/api/users'response = requests.get(url, timeout=30)parsed = response.json()print(parsed)except requests.exceptions.ConnectionError:# 👇? 在此處處理錯誤或使用 `pass` 語句print('connection error occurred')make_request()
如果 try
塊中出現(xiàn)連接錯誤,except
塊將運行。
禁用 SSL 證書驗證
如果由于請求無法驗證站點的 SSL 證書而收到錯誤,您可以將驗證關鍵字參數(shù)設置為 False 以禁用請求的 SSL 證書驗證。
請注意
,我們應該只在本地開發(fā)或測試期間禁用 SSL 證書驗證,因為它可能會使我們的應用程序容易受到中間人攻擊。
import requestsdef make_request():try:url = 'https://example.com/api/users'# 👇? 將驗證設置為 Falseresponse = requests.get(url, verify=False, timeout=30)parsed = response.json()print(parsed)except Exception as e:print(e)make_request()
使用 time.sleep() 方法實現(xiàn)請求之間的延遲
另一種解決方案是使用 time.sleep()
方法在請求之間設置一定的延遲。
API 可能會限制我們的請求,這可能不會延遲發(fā)生。
from time import sleep
import requestsdef make_request():try:url = 'https://example/api/users'response = requests.get(url, timeout=30)parsed = response.json()print(parsed['data'][0])except requests.exceptions.ConnectionError:# 👇? 在此處處理錯誤或使用 `pass` 語句print('connection error occurred')for i in range(3):make_request()sleep(1.5)
time.sleep
方法暫停執(zhí)行給定的秒數(shù)。
代碼示例以 1.5 秒的延遲向 API 發(fā)出 3 個請求。
重復請求直到成功響應
我們還可以使用 while 循環(huán)重復請求,直到服務器響應。
from time import sleep
import requestsresponse = Nonewhile response is None:try:url = 'https://example.com/api/users'response = requests.get(url, timeout=30)breakexcept:print('Connection error occurred')sleep(1.5)continueprint(response)
parsed = response.json()
print(parsed)
我們使用 while
循環(huán)每 1.5 秒發(fā)出一次請求,直到服務器無連接錯誤地響應。
try
語句嘗試向 API 發(fā)出 HTTP 請求,如果請求失敗,except 塊將在我們暫停執(zhí)行 1.5 秒的地方運行。
continue
語句用于繼續(xù) while 循環(huán)的下一次迭代。
重復該過程,直到 HTTP 請求成功并使用 break 語句。
我們還可以在代碼的錯誤處理部分更加具體。
from time import sleep
import requestsresponse = Nonewhile response is None:try:url = 'https://example.com/api/users'response = requests.get(url, timeout=30)breakexcept requests.ConnectionError as e:print('Connection error occurred', e)sleep(1.5)continueexcept requests.Timeout as e:print('Timeout error - request took too long', e)sleep(1.5)continueexcept requests.RequestException as e:print('General error', e)sleep(1.5)continueexcept KeyboardInterrupt:print('The program has been canceled')print(response)
parsed = response.json()
print(parsed)
requests.ConnectionError
錯誤意味著我們的站點或服務器上存在連接問題。
檢查我們的互聯(lián)網(wǎng)連接并確保服務器可以訪問互聯(lián)網(wǎng)。
requests.Timeout
錯誤在請求花費的時間太長時引發(fā)(在示例中超過 30 秒)。
requests.RequestException
錯誤是一個通用的、包羅萬象的錯誤。
當用戶取消程序時會引發(fā) KeyboardInterrupt
異常,例如 按 CTRL + C。
總結
要解決錯誤“ConnectionError: Max retries exceeded with url”,請確保:
- 在調(diào)用
request.get()
時指定正確且完整的 URL。 - 不受 API 的速率限制。
- requests 模塊能夠驗證站點的 SSL 證書。
- 可以訪問互聯(lián)網(wǎng)。