Cómo atrapar el error 404 en urllib.urlretrieve

Antecedentes: estoy usando urllib.urlretrieve , a diferencia de cualquier otra función en los módulos urllib* , debido al soporte de la función de enganche (consulte el reporthook continuación) .. que se usa para mostrar una barra de progreso textual. Esto es Python> = 2.6.

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

Sin embargo, urlretrieve es tan tonto que no deja ninguna forma de detectar el estado de la solicitud HTTP (por ejemplo: ¿fue 404 o 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 '' >>> 

¿Cuál es la forma más conocida de descargar un archivo HTTP remoto con soporte tipo gancho (para mostrar la barra de progreso) y un manejo de errores HTTP decente?

Verifique el código completo de 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) 

En otras palabras, puede usar urllib.FancyURLopener (es parte de la API pública de urllib). Puede anular http_error_default para detectar 404s:

 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) 

Deberías usar:

 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) 

Edit: El razonamiento aquí es que a menos que espere el estado excepcional, es una excepción para que suceda, y probablemente ni siquiera lo pensó, así que en lugar de dejar que su código continúe ejecutándose mientras no tuvo éxito, El comportamiento predeterminado es, con bastante sensatez, nhibernate su ejecución.

El método “retreive” del objeto abridor de URL admite el reporthook y lanza una excepción en 404.

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