47 votes

Comment empêcher urllib(2) de Python de suivre une redirection ?

J'essaie actuellement de me connecter à un site en utilisant Python, mais le site semble envoyer un cookie et une déclaration de redirection sur la même page. Python semble suivre cette redirection, ce qui m'empêche de lire le cookie envoyé par la page de connexion. Comment empêcher l'urllib (ou urllib2) urlopen de Python de suivre la redirection ?

33voto

pope Points 520

Vous pouvez faire plusieurs choses :

  1. Créez votre propre HTTPRedirectHandler qui intercepte chaque redirection
  2. Créez une instance de HTTPCookieProcessor et installez cet ouvreur afin d'avoir accès au cookiejar.

Il s'agit d'une petite chose rapide qui montre à la fois

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

29voto

Alan Duan Points 171

Si tout ce dont vous avez besoin est d'arrêter la redirection, il existe un moyen simple de le faire. Par exemple, je veux seulement obtenir des cookies et pour une meilleure performance, je ne veux pas être redirigé vers une autre page. J'espère également que le code est conservé en tant que 3xx. Utilisons 302 par exemple.

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 cette façon, vous n'avez même pas besoin d'aller dans urllib2.HTTPRedirectHandler.http_error_302()

Le cas le plus fréquent est celui où l'on souhaite simplement arrêter la redirection (si nécessaire) :

class NoRedirection(urllib2.HTTPErrorProcessor):

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

    https_response = http_response

Et normalement, il est utilisé de cette manière :

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']

12voto

joeforker Points 14483

urllib2.urlopen appels build_opener() qui utilise cette liste de classes de gestionnaires :

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

Vous pouvez essayer d'appeler urllib2.build_opener(handlers) avec une liste qui omet HTTPRedirectHandler puis appeler le open() sur le résultat pour ouvrir votre URL. Si vous n'aimez vraiment pas les redirections, vous pouvez même appeler urllib2.install_opener(opener) vers votre propre ouvreur non redirigeant.

Il semble que votre véritable problème soit le suivant urllib2 ne fait pas les cookies comme vous le souhaiteriez. Voir aussi Comment utiliser Python pour se connecter à une page web et récupérer les cookies pour une utilisation ultérieure ?

3voto

paprika Points 1622

Cette question a été posée auparavant ici .

EDIT : Si vous avez affaire à des applications web bizarres, vous devriez probablement essayer mécaniser . Il s'agit d'une excellente bibliothèque qui simule un navigateur web. Vous pouvez contrôler les redirections, les cookies, les rafraîchissements de pages... Si le site web ne repose pas [fortement] sur JavaScript, vous vous entendrez très bien avec Mechanize.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X