2009-08-20 13 views
25

पृष्ठभूमि: मैं urllib.urlretrieve उपयोग कर रहा हूँ, के रूप में urllib* मॉड्यूल में किसी अन्य समारोह के लिए विरोध किया, हुक समारोह समर्थन की वजह से (नीचे reporthook देखें) .. जो एक टेक्स्ट प्रदर्शित करने के लिए प्रयोग किया जाता है प्रगति पट्टी। यह पायथन> = 2.6 है।कैसे urllib.urlretrieve में 404 त्रुटि को पकड़ने के लिए

>>> urllib.urlretrieve(url[, filename[, reporthook[, data]]]) 

हालांकि, urlretrieve कि यह HTTP अनुरोध की स्थिति का पता लगाने का कोई तरीका नहीं छोड़ देता है तो गूंगा है (उदाहरण के लिए: यह 404 या 200 था?)।

>>> fn, h = urllib.urlretrieve('http://google.com/foo/bar') 
>>> h.items() 
[('date', 'Thu, 20 Aug 2009 20:07:40 GMT'), 
('expires', '-1'), 
('content-type', 'text/html; charset=ISO-8859-1'), 
('server', 'gws'), 
('cache-control', 'private, max-age=0')] 
>>> h.status 
'' 
>>> 

हुक की तरह समर्थन के साथ एक दूरस्थ HTTP फ़ाइल डाउनलोड करने के लिए सबसे अच्छा ज्ञात तरीका क्या है और एक सभ्य HTTP त्रुटि हैंडलिंग (प्रगति बार दिखाने के लिए)?

+0

आपके अनुरोध पर HTTP स्थिति प्रदान नहीं करना शायद stdlib में एक बग माना जाना चाहिए (लेकिन नीचे बेहतर लाइब्रेरी, अनुरोध, नीचे देखें) –

उत्तर

27

urllib.urlretrieve के पूरा कोड चेक आउट:

def urlretrieve(url, filename=None, reporthook=None, data=None): 
    global _urlopener 
    if not _urlopener: 
    _urlopener = FancyURLopener() 
    return _urlopener.retrieve(url, filename, reporthook, data) 

दूसरे शब्दों में, आप urllib.FancyURLopener (यह सार्वजनिक urllib एपीआई का हिस्सा) का उपयोग कर सकते हैं। आप 404 का पता लगाने के http_error_default ओवरराइड कर सकते हैं:

class MyURLopener(urllib.FancyURLopener): 
    def http_error_default(self, url, fp, errcode, errmsg, headers): 
    # handle errors the way you'd like to 

fn, h = MyURLopener().retrieve(url, reporthook=my_report_hook) 
+0

मैं हैंडलर निर्दिष्ट नहीं करना चाहता; क्या यह urllib2.urlopen जैसे अपवाद फेंकता है? –

+4

इसे फेंकना बहुत आसान है। FancyURLopener subclasses URLopener जो फेंकता है, इसलिए आप बेस क्लास के कार्यान्वयन को कॉल करने का प्रयास कर सकते हैं: def http_error_default (...): URLopener.http_error_default (...) – orip

+0

यह एक बहुत अच्छा समाधान है, मैंने अभी इसे स्वयं उपयोग किया है। –

2

यूआरएल ओपनर वस्तु के "पुनर्प्राप्त" विधि reporthook का समर्थन करता है और 404.

http://docs.python.org/library/urllib.html#url-opener-objects

+0

हां, लेकिन यह रीडायरेक्ट का समर्थन नहीं करता है, आदि .. –

14

पर एक अपवाद आप का उपयोग करना चाहिए फेंकता है:

import urllib2 

try: 
    resp = urllib2.urlopen("http://www.google.com/this-gives-a-404/") 
except urllib2.URLError, e: 
    if not hasattr(e, "code"): 
     raise 
    resp = e 

print "Gave", resp.code, resp.msg 
print "=" * 80 
print resp.read(80) 

संपादित करें: यहां तर्क यह है कि जब तक आप असाधारण सेंट की अपेक्षा नहीं करते खा लिया, यह होने के लिए एक अपवाद है, और आपने शायद इसके बारे में भी सोचा नहीं है - इसलिए असफल होने पर आपके कोड को चलाने के बजाए, डिफ़ॉल्ट व्यवहार - काफी समझदारी से - इसे बाधित करने के लिए निष्पादन।

+2

हुक-जैसी समर्थन? –

+1

श्रीधर, http://stackoverflow.com/a/9740603/819417 देखें –

संबंधित मुद्दे