簡體   English   中英

如何在 try except 場景中捕獲 HTTP Error 429“Retry-After”時間?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM