52 votes

Python: urllib/urllib2/httplib confusion

Je suis en train de tester la fonctionnalité d'une application web par le script d'une séquence de connexion en Python, mais je vais avoir quelques problèmes.

Voici ce que je dois faire:

  1. Faire un POST avec un peu de paramètres et les en-têtes.
  2. Suivre une redirection
  3. Récupérer le code HTML du corps.

Maintenant, je suis relativement nouveau à python, mais les deux choses que j'ai testé jusqu'à présent n'ont pas travaillé. J'ai d'abord utilisé httplib, avec putrequest() (passer les paramètres dans l'URL), et putheader(). Cela ne semble pas suivre les redirections.

Ensuite, j'ai essayé urllib et urllib2, en passant les deux en-têtes et les paramètres dicts. Cela semble revenir à la page de connexion, au lieu de la page que je suis en train de login, je suppose que c'est à cause de l'absence de témoins ou de quelque chose.

Ai-je raté quelque chose de simple?

Merci.

31voto

S.Lott Points 207588

Focus sur urllib2 pour cela, il fonctionne très bien. Ne salissez pas avec httplib, ce n'est pas l'API de niveau supérieur.

Ce que vous êtes de noter que, urllib2 ne pas suivre la redirection.

Vous avez besoin de plier dans une instance de HTTPRedirectHandler qui va attraper et de suivre les redirections.

En outre, vous pouvez créer des sous-classes par défaut HTTPRedirectHandler pour capturer des informations que vous pourrez ensuite vérifier dans le cadre de vos tests unitaires.

cookie_handler= urllib2.HTTPCookieProcessor( self.cookies )
redirect_handler= HTTPRedirectHandler()
opener = urllib2.build_opener(redirect_handler,cookie_handler)

Vous pouvez ensuite utiliser cette opener objet de POST et GET, la manipulation des redirections et les cookies correctement.

Vous pouvez ajouter vos propres sous-classe de la HTTPHandler de la capture et du journal des différents codes d'erreur, aussi.

15voto

Jason Pepas Points 151

Voici mon point de vue sur cette question.

#!/usr/bin/env python

import urllib
import urllib2


class HttpBot:
    """an HttpBot represents one browser session, with cookies."""
    def __init__(self):
        cookie_handler= urllib2.HTTPCookieProcessor()
        redirect_handler= urllib2.HTTPRedirectHandler()
        self._opener = urllib2.build_opener(redirect_handler, cookie_handler)

    def GET(self, url):
        return self._opener.open(url).read()

    def POST(self, url, parameters):
        return self._opener.open(url, urllib.urlencode(parameters)).read()


if __name__ == "__main__":
    bot = HttpBot()
    ignored_html = bot.POST('https://example.com/authenticator', {'passwd':'foo'})
    print bot.GET('https://example.com/interesting/content')
    ignored_html = bot.POST('https://example.com/deauthenticator',{})

13voto

Ace Points 3076

@S. Lott, je vous remercie. Votre suggestion a fonctionné pour moi, avec certaines modifications. Voici comment je l'ai fait.

data = urllib.urlencode(params)
url = host+page
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)

cookies = CookieJar()
cookies.extract_cookies(response,request)

cookie_handler= urllib2.HTTPCookieProcessor( cookies )
redirect_handler= HTTPRedirectHandler()
opener = urllib2.build_opener(redirect_handler,cookie_handler)

response = opener.open(request)

11voto

Eli Courtwright Points 53071

J'ai eu à faire cette chose exacte que moi-même récemment. J'ai seulement besoin des classes de la bibliothèque standard. Voici un extrait de mon code:

from urllib import urlencode
from urllib2 import urlopen, Request

# encode my POST parameters for the login page
login_qs = urlencode( [("username",USERNAME), ("password",PASSWORD)] )

# extract my session id by loading a page from the site
set_cookie = urlopen(URL_BASE).headers.getheader("Set-Cookie")
sess_id = set_cookie[set_cookie.index("=")+1:set_cookie.index(";")]

# construct headers dictionary using the session id
headers = {"Cookie": "session_id="+sess_id}

# perform login and make sure it worked
if "Announcements:" not in urlopen(Request(URL_BASE+"login",headers=headers), login_qs).read():
    print "Didn't log in properly"
    exit(1)

# here's the function I used after this for loading pages
def download(page=""):
    return urlopen(Request(URL_BASE+page, headers=headers)).read()

# for example:
print download(URL_BASE + "config")

8voto

Je donnerais Mécaniser (http://wwwsearch.sourceforge.net/mechanize/) un coup de feu. Il peut bien gérer votre cookie/en-têtes, de manière transparente.

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