¿Cómo puedo evitar que urllib (2) de Python siga una redirección?

Actualmente estoy intentando iniciar sesión en un sitio usando Python, sin embargo, el sitio parece estar enviando una cookie y una statement de redireccionamiento en la misma página. Python parece estar siguiendo esa redirección, lo que me impide leer la cookie enviada por la página de inicio de sesión. ¿Cómo puedo evitar que urllib (o urllib2) de Python siga el redireccionamiento?

Podrías hacer un par de cosas:

  1. Construya su propio HTTPRedirectHandler que intercepta cada redirección
  2. Cree una instancia de HTTPCookieProcessor e instale ese abridor para que tenga acceso al cookiejar.

Esto 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 

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, ni siquiera necesita ingresar a urllib2.HTTPRedirectHandler.http_error_302 ()

Sin embargo, un caso más común es que simplemente queremos detener la 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 usamos 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'] 

urllib2.urlopen llama a build_opener() que usa esta lista de clases de manejador:

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

Puede intentar llamar a urllib2.build_opener(handlers) con una lista que omita HTTPRedirectHandler , luego llamar al método open() en el resultado para abrir su URL. Si realmente no le gustan los redireccionamientos, incluso podría llamar a urllib2.install_opener(opener) a su propio abridor que no redirecciona.

Parece que su verdadero problema es que urllib2 no está haciendo las cookies de la forma que le gustaría. Consulte también ¿Cómo utilizar Python para iniciar sesión en una página web y recuperar cookies para su uso posterior?

Esta pregunta fue hecha antes de aquí .

EDITAR: Si tiene que lidiar con aplicaciones web extravagantes, probablemente debería probar mecanizar . Es una gran biblioteca que simula un navegador web. Puede controlar el redireccionamiento, las cookies, las actualizaciones de la página … Si el sitio web no se basa [en gran medida] en JavaScript, se llevará muy bien con mecanizar.