2009-02-16 13 views
43

Actualmente estoy tratando de iniciar sesión en un sitio usando Python; sin embargo, el sitio parece estar enviando una cookie y una declaración de redirección en la misma página. Python parece estar siguiendo ese redireccionamiento, impidiéndome leer la cookie enviada por la página de inicio de sesión. ¿Cómo evito que urllib (o urllib2) urlopen de Python siga el redireccionamiento?Cómo evito que el urllib (2) de Python siga un redireccionamiento

+0

Du plicate: http://stackoverflow.com/questions/110498/is-there-an-easy-way-to-request-a-url-in-python-and-not-follow-redirects/110808 –

+0

una pregunta similar: http://stackoverflow.com/questions/9890815/python-get-headers-only-using-urllib2 – newtover

Respuesta

33

que podría hacer un par de cosas:

  1. Construye tu propia HTTPRedirectHandler que intercepta cada redirigir
  2. Crear una instancia de HTTPCookieProcessor e instalar que el abridor para que tenga acceso a la CookieJar.

Ésta es una pequeña cosa rápida que muestra tanto

import urllib2 

#redirect_handler = urllib2.HTTPRedirectHandler() 

class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler): 
    def http_error_302(self, req, fp, code, msg, headers): 
     print "Cookie Manip Right Here" 
     return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers) 

    http_error_301 = http_error_303 = http_error_307 = http_error_302 

cookieprocessor = urllib2.HTTPCookieProcessor() 

opener = urllib2.build_opener(MyHTTPRedirectHandler, cookieprocessor) 
urllib2.install_opener(opener) 

response =urllib2.urlopen("WHEREEVER") 
print response.read() 

print cookieprocessor.cookiejar 
+0

Parece que no está usando' redirect_handler = urllib2.HTTPRedirectHandler() 'en el ejemplo. ¿Vas a mostrar un segundo ejemplo? –

+0

Tiene razón, no estoy usando el redirect_handler. En cambio, creé mi propio controlador de redirección. Editaré para eliminar. – pope

+0

¿Por qué no necesita crear una instancia del 'MyHTTPRedirectHandler', sino pasar la clase al método' build_opener() '? – Benjamin

11

urllib2.urlopen llama build_opener() que utiliza esta lista de clases de controlador:

handlers = [ProxyHandler, UnknownHandler, HTTPHandler, 
HTTPDefaultErrorHandler, HTTPRedirectHandler, 
FTPHandler, FileHandler, HTTPErrorProcessor] 

usted podría intentar llamar urllib2.build_opener(handlers) a sí mismo con una lista que omite HTTPRedirectHandler, a continuación, llamar al método open() en el resultado de abrir su dirección URL. Si realmente no le gustan los redireccionamientos, incluso puede llamar al urllib2.install_opener(opener) a su propio abridor sin redireccionamiento.

Parece que su verdadero problema es que urllib2 no está haciendo las cookies de la manera que desee. Consulte también How to use Python to login to a webpage and retrieve cookies for later usage?

+6

* Puede intentar llamar urllib2.build_opener (handlers) usted mismo con una lista que omita HTTPRedirectHandler, luego llame al método open() sobre el resultado para abrir su URL. * Bueno, documentos para urllib2.build_opener() dice esto * Las instancias de las siguientes clases ** estarán delante de los manejadores **, a menos que los manejadores las contengan, instancias de ellas o subclases de ellas: ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler , HTTPErrorProcessor. * Parece que omitir 'HTTPRedirectHandler' no funcionará ... –

3

Esta pregunta se realizó antes del here.

EDIT: Si tiene que lidiar con aplicaciones web peculiares, probablemente debería probar mechanize. Es una gran biblioteca que simula un navegador web. Puedes controlar el redireccionamiento, las cookies, las actualizaciones de página ... Si el sitio web no depende [en gran medida] de JavaScript, te llevarás muy bien con mechanize.

28

Si todo lo que necesita es detener la redirección, entonces hay una forma sencilla de hacerlo. Por ejemplo, solo quiero obtener cookies y, para un mejor rendimiento, no quiero ser redirigido a ninguna otra página. También espero que el código se mantenga como 3xx. usemos 302 por ejemplo.

class MyHTTPErrorProcessor(urllib2.HTTPErrorProcessor): 

    def http_response(self, request, response): 
     code, msg, hdrs = response.code, response.msg, response.info() 

     # only add this line to stop 302 redirection. 
     if code == 302: return response 

     if not (200 <= code < 300): 
      response = self.parent.error(
       'http', request, response, code, msg, hdrs) 
     return response 

    https_response = http_response 

cj = cookielib.CookieJar() 
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj), MyHTTPErrorProcessor) 

De esta manera, usted ni siquiera necesita para entrar en urllib2.HTTPRedirectHandler.http_error_302()

caso aún más común es que simplemente queremos dejar de redirección (según sea necesario):

class NoRedirection(urllib2.HTTPErrorProcessor): 

    def http_response(self, request, response): 
     return response 

    https_response = http_response 

Y normalmente lo utilizan de esta manera:

cj = cookielib.CookieJar() 
opener = urllib2.build_opener(NoRedirection, urllib2.HTTPCookieProcessor(cj)) 
data = {} 
response = opener.open('http://www.example.com', urllib.urlencode(data)) 
if response.code == 302: 
    redirection_target = response.headers['Location'] 
+1

Justo lo que necesitaba, y muy concisa 'clase NoRedirection()' - ni siquiera tiene que almacenar 'code, msg, hdrs' - Gracias Alan. –

+0

¡Tienes razón! Y eliminé la línea como sugeriste. Gracias Xtof. –

+0

¿Es posible utilizar este enfoque para obtener la URL de redireccionamiento real? – AdjunctProfessorFalcon

Cuestiones relacionadas