web-dev-qa-db-fra.com

Comment puis-je empêcher Python urllib2) de suivre une redirection

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

47
Jack Edmonds

Vous pouvez faire deux ou trois choses:

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

Ceci est 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
33
pope

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 de meilleures performances, je ne veux pas être redirigé vers une autre page. J'espère également que le code sera conservé en 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 ()

Pourtant, le cas le plus courant est que nous voulons 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 utilisez-le normalement de cette façon:

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']
29
Alan Duan

urllib2.urlopen Appelle 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) vous-même avec une liste qui omet HTTPRedirectHandler, puis appelez la méthode open() sur le résultat pour ouvrir votre URL. Si vous n'aimez pas vraiment les redirections, vous pouvez même appeler urllib2.install_opener(opener) vers votre propre ouvreur sans redirection.

Il semble que votre vrai problème est que urllib2 Ne fait pas les cookies comme vous le souhaitez. Voir aussi Comment utiliser Python pour se connecter à une page Web et récupérer des cookies pour une utilisation ultérieure?

12
joeforker

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

ÉDITER: Si vous devez gérer des applications Web originales, vous devriez probablement essayer mécaniser . C'est une excellente bibliothèque qui simule un navigateur Web. Vous pouvez contrôler la redirection, les cookies, l'actualisation des pages ... Si le site ne s'appuie pas [fortement] sur JavaScript, vous vous entendrez très bien avec la mécanisation.

3
paprika