[英]How do I catch the HTTP Error 429 "Retry-After" time in a try except scenario?
我創建了一個 python 腳本,它使用 urllib 從 met.no 獲取信息。 它是這樣的:
from urllib.request import Request, urlopen
from urllib.error import HTTPError
from urllib.error import URLError
import json
import datetime, time
from datetime import datetime
from dateutil import tz
def get_info_from_yr():
url = 'https://api.met.no/weatherapi/locationforecast/2.0/compact?lat70&lon=j8'
headers = {
'User-Agent': 'Python User Agent 1.0',
'From': 'what@ever.com'
}
request = Request(
url=url,
headers= headers,
method='GET')
try:
result = urlopen(request, timeout=5)
except HTTPError as http_error:
if http_error.status == 429:
print ("We must wait!")
time.sleep(int(result.headers["Retry-After"]))
else:
print(f"Could not reach {request.full_url} due to an error: {http_error}")
except URLError as url_error:
print (f" A URL Error occured: {url_error}")
except Exception as generic_http_error:
print (f" A URL exception occured: {generic_http_error}")
else:
data = json.load(result)
#print (result.status)
http_expiry_date = convert_date_from_gmt(result.headers['Expires'])
yr_data = {
"expiry_date": http_expiry_date,
"temperature": data["properties"]["timeseries"][0]["data"]["instant"]["details"]["air_temperature"]
}
try:
with open("yr_data.json", "w") as wj:
wj.write(json.dumps(yr_data, indent=2))
except IOError as io_error:
print(f" There was an IOErorr: {io_error}")
except Exception as generic_io_error:
print (f"An IO exception occured: {generic_io_error}")
但是如果我引發 HTTP 429 錯誤,我會得到這個錯誤: time.sleep(int(result.headers["Retry-After"])) UnboundLocalError: local variable 'result' referenced before assignment
結果變量似乎沒有出現在 except 塊中。 那么我真的不明白如何捕捉“重試之后” header
我嘗試以多種不同的方式捕捉“重試后”header,但沒有人堅持
有關如何解決此問題的任何提示?
我當然可以設置一個 static 計時器,但這有它自己的缺點。
謝謝
根據文檔,您可以從HTTPError
訪問響應,其中包含響應的標頭。
運行您提供的 URL,我可以獲得 400 響應,將您的except HTTPError as http_error
塊:
except HTTPError as http_error:
if http_error.status == 429:
print("We must wait!")
time.sleep(int(result.headers["Retry-After"]))
else:
print(http_error.headers.items())
retry_after = next((x for x in http_error.headers.items() if x[0] == "X-Backend-Host"), ("dummy", "Retry After not found, use some default value here"))[1]
print(retry_after)
print(f"Could not reach {request.full_url} due to an error: {http_error}")
回報:
[ilias@yellowhat-37 PYTHON_LEARNING] > ./requests_403.py
[('Server', 'nginx/1.18.0 (Ubuntu)'), ('Date', 'Tue, 31 Jan 2023 20:58:58 GMT'), ('Content-Type', 'text/plain;charset=UTF-8'), ('Content-Length', '122'), ('Connection', 'close'), ('X-ErrorClass', 'Parameter'), ('Expires', '0'), ('Cache-Control', 'private, max-age=0, no-cache, no-store, must-revalidate'), ('X-Backend-Host', 'b_157_249_72_213_loc'), ('X-Varnish', '59429260'), ('Age', '0'), ('Via', '1.1 varnish (Varnish/7.0)')]
b_157_249_72_213_loc
Could not reach https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=70&lon=k8 due to an error: HTTP Error 400: Bad Request
[ilias@yellowhat-37 PYTHON_LEARNING] >
它確實可以提供響應的標題。
(您會注意到我已經用X-Backend-Host
替換了 header retry-after
的重試以進行概念驗證。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.