2012-02-25 13 views
26

जब urllib2.request टाइमआउट तक पहुंचता है, तो urllib2.URLError अपवाद उठाया जाता है। कनेक्शन स्थापित करने के लिए पाइथोनिक तरीका क्या है?विफल होने पर urllib2.request को पुनः प्रयास कैसे करें?

+1

इस प्रश्न का उत्तर आपके उत्तर देना चाहिए: http://stackoverflow.com/questions/2712524/handling-urllib2s-timeout-python –

+2

मैंने यह नहीं पूछा कि निरीक्षण कैसे प्राप्त करें। मैं जानना चाहता था कि कनेक्शन स्थापित करने के लिए एक पाइथोनिक तरीका है या नहीं। – iTayb

+0

क्षमा करें, मुझे लगता है कि समस्या को फिर से स्थापित करने में नहीं, टाइमआउट का पता लगाने में समस्या थी। क्या आप अपवाद ब्लॉक में urlopen() को कॉल नहीं कर सकते? –

उत्तर

52

मैं retry सजावट का उपयोग करूंगा। वहां अन्य लोग हैं, लेकिन यह बहुत अच्छी तरह से काम करता है। यहाँ कैसे आप इसका इस्तेमाल कर सकते हैं:

@retry(urllib2.URLError, tries=4, delay=3, backoff=2) 
def urlopen_with_retry(): 
    return urllib2.urlopen("http://example.com") 

इस समारोह का पुनः प्रयास करेगा अगर URLError उठाया जाता है। पैरामीटर पर दस्तावेज़ीकरण के लिए ऊपर दिए गए लिंक को चेक करें, लेकिन मूल रूप से यह अधिकतम 4 बार पुनः प्रयास करेगा, प्रत्येक घातीय दोगुना विलंब प्रत्येक बार दोगुना हो जाएगा, उदा। 3 सेकंड, 6 सेकंड, 12 सेकंड।

+1

यह वास्तव में एक अच्छा स्निपेट है। क्या आप एक विकल्प जानते हैं, लेकिन एक संदर्भ प्रबंधक के रूप में? –

+0

हम्म, मुझे लगता है कि आप शायद इसे संदर्भ प्रबंधक के रूप में आसानी से लिख सकते हैं, लेकिन मेरे पास एक ऑफहेड नहीं है। – jterrace

+0

ऐसा करना आसान नहीं है, क्योंकि कथन के अंदर ब्लॉक को कैप्चर करने का कोई आसान तरीका नहीं है। आपको कुछ गहरे आत्मनिरीक्षण की आवश्यकता है। –

3

टाइमआउट पर पुन: प्रयास करने के लिए आप @Karl Barker suggested in the comment के रूप में अपवाद पकड़ सकते थे:

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 
4

वहाँ बाहर कुछ पुस्तकालयों है कि इस के विशेषज्ञ हैं।

एक backoff है, जो विशेष रूप से कार्यात्मक संवेदनशीलता के साथ बनाया गया है। सजावटी मनमाने ढंग से कॉलबेल जेनरेटर लौट रहे हैं जो लगातार देरी मूल्य प्रदान करते हैं।

@backoff.on_exception(backoff.expo, 
         urllib2.URLError, 
         max_value=32) 
def url_open(url): 
    return urllib2.urlopen("http://example.com") 

एक और retrying है जो बहुत ही इसी तरह की सुविधा है, लेकिन एक API जहां मानकों पुन: प्रयास पूर्वनिर्धारित कीवर्ड आर्ग के माध्यम से निर्दिष्ट कर रहे हैं: के रूप में 32 सेकंड की अवधि वाले पुन: प्रयास करें समय के साथ एक सरल घातीय backoff में परिभाषित किया जा सकता है।