2011-08-11 16 views
17

Según the urllib2 documentation,¿Por qué el urllib2.urlopen() de Python genera un HTTPError para códigos de estado exitosos?

Debido a que los controladores predeterminados manejar las redirecciones (códigos en el rango de 300), y códigos en el rango de 100-299 indican el éxito, por lo general sólo se ve códigos de error en el rango de 400 a 599 .

Y sin embargo, el siguiente código

request = urllib2.Request(url, data, headers) 
response = urllib2.urlopen(request) 

plantea una HTTPError con código 201 (creado):

ERROR 2011-08-11 20:40:17,318 __init__.py:463] HTTP Error 201: Created 

¿Por qué es urllib2 lanzando httpErrors sobre esta solicitud exitosa?

No es demasiado doloroso; Puedo extender fácilmente el código para:

try: 
    request = urllib2.Request(url, data, headers) 
    response = urllib2.urlopen(request) 
except HTTPError, e: 
    if e.code == 201: 
     # success! :) 
    else: 
     # fail! :(
else: 
    # when will this happen...? 

Pero este no parece ser el comportamiento previsto, en base a la documentación y el hecho de que no puedo encontrar las preguntas similares sobre este extraño comportamiento.

Además, lo que debe esperar el bloque else? Si todos los códigos de estado exitosos se interpretan como HTTPError s, ¿cuándo devuelve el objeto de respuesta normal similar a un archivo urllib2.urlopen() el que se refiere a la documentación de urllib2?

+0

Es muy raro ver respuesta de códigos entre 201-299. No me sorprende que urllib2 no los maneje perfectamente. – Leopd

+1

¿Me estoy perdiendo algo? 201 funciona bien para mí ... – Santa

+0

@Santa, ¿quizás estás usando un controlador no estándar, según la respuesta de dcrosta? – rubergly

Respuesta

3

A medida que la biblioteca de documentación real menciones:

para 200 códigos de error, el objeto respuesta se devuelve inmediatamente.

Para los códigos de error que no sean 200, esto simplemente pasa el trabajo a los métodos del manejador de código_ protocol_, a través de OpenerDirector.error(). Finalmente, urllib2.HTTPDefaultErrorHandler generará un HTTPError si ningún otro manejador maneja el error.

http://docs.python.org/library/urllib2.html#httperrorprocessor-objects

16

Puede escribir una clase personalizada Handler para su uso con urllib2 para evitar que los códigos de error específicos no se planteó como HTTError. Aquí hay una que he usado antes:

class BetterHTTPErrorProcessor(urllib2.BaseHandler): 
    # a substitute/supplement to urllib2.HTTPErrorProcessor 
    # that doesn't raise exceptions on status codes 201,204,206 
    def http_error_201(self, request, response, code, msg, hdrs): 
     return response 
    def http_error_204(self, request, response, code, msg, hdrs): 
     return response 
    def http_error_206(self, request, response, code, msg, hdrs): 
     return response 

A continuación, puede usarla como:

opener = urllib2.build_opener(self.BetterHTTPErrorProcessor) 
urllib2.install_opener(opener) 

req = urllib2.Request(url, data, headers) 
urllib2.urlopen(req) 
+0

¿Cómo se verifica el código de respuesta en estos casos? –

Cuestiones relacionadas