web-dev-qa-db-fra.com

Connectez-vous au site Web en utilisant urllib2 - Python 2.7

D'accord, donc j'utilise ceci pour un bot reddit, mais je veux pouvoir comprendre COMMENT se connecter à n'importe quel site Web. Si ça a du sens....

Je me rends compte que différents sites Web utilisent différents formulaires de connexion, etc. Alors, comment puis-je déterminer comment l'optimiser pour chaque site Web? Je suppose que je dois chercher quelque chose dans le fichier html mais aucune idée de quoi.

Je ne veux PAS utiliser Mechanize ou toute autre bibliothèque (c'est ce dont parlent toutes les autres réponses ici et ne m'aide pas vraiment à apprendre ce qui se passe), car je veux apprendre par moi-même comment tout cela fonctionne exactement.

La documentation urllib2 ne m'aide vraiment pas.

Merci.

36
tommo

Je préfère ceci en disant que je ne me suis pas connecté de cette manière depuis un certain temps, donc je pourrais manquer certaines des façons les plus "acceptées" de le faire.

Je ne sais pas si c'est ce que vous recherchez, mais sans bibliothèque comme mechanize ou un framework plus robuste comme Selenium, dans le cas de base, vous regardez simplement le formulaire lui-même et recherchez le inputs. Par exemple, en regardant www.reddit.com, puis en visualisant la source de la page rendue, vous trouverez ce formulaire:

<form method="post" action="https://ssl.reddit.com/post/login" id="login_login-main"
  class="login-form login-form-side">
    <input type="hidden" name="op" value="login-main" />
    <input name="user" placeholder="username" type="text" maxlength="20" tabindex="1" />
    <input name="passwd" placeholder="password" type="password" tabindex="1" />

    <div class="status"></div>

    <div id="remember-me">
      <input type="checkbox" name="rem" id="rem-login-main" tabindex="1" />
      <label for="rem-login-main">remember me</label>
      <a class="recover-password" href="/password">reset password</a>
    </div>

    <div class="submit">
      <button class="btn" type="submit" tabindex="1">login</button>
    </div>

    <div class="clear"></div>
</form>

Nous voyons ici quelques input - op, user, passwd et rem. Notez également le paramètre action - qui est l'URL vers laquelle le formulaire sera publié, et sera donc notre cible. Alors maintenant, la dernière étape consiste à compresser les paramètres dans une charge utile et à les envoyer sous forme de demande POST à l'URL action. Également ci-dessous, nous créons un nouveau opener, ajoutons la possibilité de gérer les cookies et ajoutons également des en-têtes, nous donnant un ouvreur légèrement plus robuste pour exécuter les requêtes):

import cookielib
import urllib
import urllib2


# Store the cookies and create an opener that will hold them
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

# Add our headers
opener.addheaders = [('User-agent', 'RedditTesting')]

# Install our opener (note that this changes the global opener to the one
# we just made, but you can also just call opener.open() if you want)
urllib2.install_opener(opener)

# The action/ target from the form
authentication_url = 'https://ssl.reddit.com/post/login'

# Input parameters we are going to send
payload = {
  'op': 'login-main',
  'user': '<username>',
  'passwd': '<password>'
  }

# Use urllib to encode the payload
data = urllib.urlencode(payload)

# Build our Request object (supplying 'data' makes it a POST)
req = urllib2.Request(authentication_url, data)

# Make the request and read the response
resp = urllib2.urlopen(req)
contents = resp.read()

Notez que cela peut devenir beaucoup plus compliqué - vous pouvez également le faire avec GMail, par exemple, mais vous devez extraire des paramètres qui changeront à chaque fois (comme le paramètre GALX). Encore une fois, je ne sais pas si c'est ce que vous vouliez, mais j'espère que cela vous aidera.

49
RocketDonkey