2009-08-20 12 views
25

背景:urllib*モジュール内の他の機能とは対照的に、フック機能のサポート(下記reporthook参照)のため、私はurllib.urlretrieveを使用しています。プログレスバー。これはPython> = 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エラーハンドリングをダウンロードするための最もよく知られている方法は何ですか? urllib.urlretrieveの完全なコード

+0

リクエストのHTTPステータスを提供していないと、おそらくstdlibのバグとみなされるはずです(ただし、以下のはるかに良いライブラリ、リクエストをチェックしてください)。 –

答えて

27

チェックアウト:つまり

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はAPIを、それの一部)を使用することができます。あなたは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は投げているURLopenerをサブクラス化しているので、基本クラスの実装を呼び出すことができます:def http_error_default(...):URLopener.http_error_default(...) – orip

+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) 

編集:ここでの論理的根拠は、例外的なstそれが起こるのは例外であり、おそらくそれについて考えることさえしなかったでしょう - そうではない間にあなたのコードを実行し続ける代わりに、デフォルトの振る舞いは - 非常に賢明に - 実行。

+2

フックのようなサポートですか? –

+1

Sridhar、http://stackoverflow.com/a/9740603/819417 –

関連する問題