いつ urllib2.request
タイムアウトに達しました、urllib2.URLError
例外が発生します。接続の確立を再試行するPythonの方法は何ですか?
retry デコレータを使用します。他にもありますが、これはかなりうまくいきます。使い方は次のとおりです。
@retry(urllib2.URLError, tries=4, delay=3, backoff=2)
def urlopen_with_retry():
return urllib2.urlopen("http://example.com")
これは、URLError
が発生した場合に関数を再試行します。上記のリンクでパラメータのドキュメントを確認しますが、基本的には最大4回再試行し、指数バックオフ遅延は毎回2倍になります。 3秒、6秒、12秒。
これに特化したライブラリがいくつかあります。
1つは backoff で、特に機能的な感性で設計されています。デコレータには、連続する遅延値を生成するジェネレータを返す任意の呼び出し可能オブジェクトが渡されます。最大再試行時間が32秒の単純な指数バックオフは、次のように定義できます。
@backoff.on_exception(backoff.expo,
urllib2.URLError,
max_value=32)
def url_open(url):
return urllib2.urlopen("http://example.com")
もう1つは retrying です。これは非常によく似た機能を備えていますが、事前定義されたキーワード引数を使用して再試行パラメーターを指定するAPIです。
タイムアウト時に再試行するには、例外をキャッチすることができます @ Karl Barkerがコメントで提案 :
assert ntries >= 1
for _ in range(ntries):
try:
page = urlopen(request, timeout=timeout)
break # success
except URLError as err:
if not isinstance(err.reason, socket.timeout):
raise # propagate non-timeout errors
else: # all ntries failed
raise err # re-raise the last timeout error
# use page here