Comment se «connecter» à un site Web en utilisant le module Requests de Python?

95

J'essaie de publier une demande de connexion à un site Web en utilisant le module Requests en Python mais cela ne fonctionne pas vraiment. Je suis nouveau dans ce domaine ... donc je ne peux pas savoir si je dois créer des cookies de nom d'utilisateur et de mot de passe ou un type d'autorisation HTTP que j'ai trouvé (??).

from pyquery import PyQuery
import requests

url = 'http://www.locationary.com/home/index2.jsp'

Alors maintenant, je pense que je suis censé utiliser "post" et cookies ...

ck = {'inUserName': 'USERNAME/EMAIL', 'inUserPass': 'PASSWORD'}

r = requests.post(url, cookies=ck)

content = r.text

q = PyQuery(content)

title = q("title").text()

print title

J'ai le sentiment que je fais mal le truc des cookies ... Je ne sais pas.

S'il ne se connecte pas correctement, le titre de la page d'accueil doit apparaître sur "Locationary.com" et si tel est le cas, ce doit être "Page d'accueil".

Si vous pouviez peut-être m'expliquer quelques choses sur les demandes et les cookies et m'aider avec cela, je l'apprécierais grandement. :RÉ

Merci.

... Cela n'a toujours pas vraiment fonctionné. D'accord ... voici donc ce que dit le code HTML de la page d'accueil avant de vous connecter:

</td><td><img src="http://www.locationary.com/img/LocationaryImgs/icons/txt_email.gif">    </td>
<td><input class="Data_Entry_Field_Login" type="text" name="inUserName" id="inUserName"  size="25"></td>
<td><img src="http://www.locationary.com/img/LocationaryImgs/icons/txt_password.gif"> </td>
<td><input  class="Data_Entry_Field_Login"  type="password" name="inUserPass"     id="inUserPass"></td>

Je pense donc que je fais les choses correctement, mais la sortie est toujours "Locationary.com"

2ème EDIT:

Je veux pouvoir rester connecté pendant une longue période et chaque fois que je demande une page sous ce domaine, je veux que le contenu s'affiche comme si j'étais connecté.

Marcus Johnson
la source

Réponses:

44

Si les informations que vous souhaitez se trouvent sur la page vers laquelle vous êtes dirigé immédiatement après la connexion ...

Appelons plutôt votre ckvariable payload, comme dans la documentation des requêtes python :

payload = {'inUserName': 'USERNAME/EMAIL', 'inUserPass': 'PASSWORD'}
url = 'http://www.locationary.com/home/index2.jsp'
requests.post(url, data=payload)

Autrement...

Voir https://stackoverflow.com/a/17633072/111362 ci-dessous.

katy lavallee
la source
Je l'ai fait fonctionner d'une manière différente en utilisant urllib, urrlib2, cookielib et quelques en-têtes HTTP.
Marcus Johnson
23
Malheureusement, je ne peux pas supprimer cela car c'est la réponse acceptée. Je ne pense pas avoir compris la question lorsque j'ai posté ceci (elle a été clarifiée après), donc je ne sais pas pourquoi elle est acceptée. Ma réponse ne fonctionne que si les données dont vous avez besoin se trouvent sur la page vers laquelle vous êtes redirigé après la connexion. @tigerFinch a une bien meilleure réponse.
katy lavallee
228

Je sais que vous avez trouvé une autre solution, mais pour ceux comme moi qui trouvent cette question, à la recherche de la même chose, cela peut être réalisé avec des demandes comme suit:

Tout d'abord, comme Marcus l'a fait, vérifiez la source du formulaire de connexion pour obtenir trois informations: l'url sur laquelle le formulaire publie et les attributs de nom des champs de nom d'utilisateur et de mot de passe. Dans son exemple, ils sont inUserName et inUserPass.

Une fois que vous avez cela, vous pouvez utiliser une requests.Session()instance pour envoyer une demande de publication à l'URL de connexion avec vos informations de connexion en tant que charge utile. Faire des requêtes à partir d'une instance de session revient essentiellement à utiliser des requêtes normalement, cela ajoute simplement de la persistance, vous permettant de stocker et d'utiliser des cookies, etc.

En supposant que votre tentative de connexion a réussi, vous pouvez simplement utiliser l'instance de session pour effectuer d'autres demandes sur le site. Le cookie qui vous identifie sera utilisé pour autoriser les demandes.

Exemple

import requests

# Fill in your details here to be posted to the login form.
payload = {
    'inUserName': 'username',
    'inUserPass': 'password'
}

# Use 'with' to ensure the session context is closed after use.
with requests.Session() as s:
    p = s.post('LOGIN_URL', data=payload)
    # print the html returned or something more intelligent to see if it's a successful login page.
    print p.text

    # An authorised request.
    r = s.get('A protected web page url')
    print r.text
        # etc...
tigre
la source
12
La question est cependant de savoir comment obtenir le formulaire de connexion POST? Comment puis-je savoir s'il s'appelle inUserName plutôt que username, USERNAME, etc.?
lsheng
4
@Twinkle regarde la source HTML du formulaire pour voir comment on les appelle.
Aaron Schumacher
3
s.text ne semble pas fonctionner, mais je vous donne toujours un peu d'amour de vote pour me montrer cette belle avec des demandes ... syntaxe
Software Prophets
s.text ne fonctionne pas car il devrait être quelque chose comme ceci: p = s.post('LOGIN_URL.....et puisp.text
Sebastian
2
@HalcyonAbrahamRamirez Je ne pense pas que ce soit le bon endroit pour demander de l'aide. Je suggère de lire la question sur votre défi spécifiquement comme: stackoverflow.com/questions/21928368/… et si vous ne pouvez pas le résoudre, ouvrez votre propre question.
Sebastian
36

Laissez-moi essayer de faire simple, supposons que l'URL du site soit http://example.com/ et supposons que vous deviez vous inscrire en remplissant le nom d'utilisateur et le mot de passe, nous allons donc à la page de connexion dire http: // exemple. com / login.php maintenant et affichez son code source et recherchez l'URL d'action, il sera sous forme de balise quelque chose comme

 <form name="loginform" method="post" action="userinfo.php">

maintenant, prenez userinfo.php pour créer une URL absolue qui sera ' http://example.com/userinfo.php ', exécutez maintenant un simple script python

import requests
url = 'http://example.com/userinfo.php'
values = {'username': 'user',
          'password': 'pass'}

r = requests.post(url, data=values)
print r.content

J'espère que cela aidera quelqu'un quelque part un jour.

Tarun Venugopal Nair
la source
1
belle - notez que parfois l'inspection de l'élément du champ name / pass peut révéler le fichier appelé plutôt que le bouton (le mien vient de dire `` action '' lors de l'inspection du bouton, l'url a été affichée en inspectant les champs usr / pass)
baxx
2
Si vous utilisez chrome, ouvrez les outils de développement sur l'onglet réseau et après avoir fait la demande, vous pouvez inspecter les valeurs réelles, avec quelles clés et où elles ont été envoyées, cela est utile pour les formulaires qui n'utilisent pas la mécanique traditionnelle et à la place utilisez javascript / ajax pour traiter le formulaire.
Roberto Arosemena
1
dans ce cas, une idée sur la façon de faire apparaître la page Web directement au lieu d'imprimer le contenu de la page?
Vous devrez utiliser le webbrowsermodule
R. Barrett le
Aussi son ci print r.content- dessus est faux, il devrait utiliserprint(r.content)
R. Barrett
6

Découvrez le nom des entrées utilisées sur le formulaire des sites Web pour les noms d'utilisateur <...name=username.../>et les mots de passe <...name=password../>et remplacez-les dans le script ci-dessous. Remplacez également l'URL pour pointer vers le site auquel vous souhaitez vous connecter.

login.py

#!/usr/bin/env python

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
payload = { 'username': '[email protected]', 'password': 'blahblahsecretpassw0rd' }
url = 'https://website.com/login.html'
requests.post(url, data=payload, verify=False)

L'utilisation de disable_warnings(InsecureRequestWarning) désactivera toute sortie du script lors de la tentative de connexion à des sites avec des certificats SSL non vérifiés.

Supplémentaire:

Pour exécuter ce script à partir de la ligne de commande sur un système UNIX, placez-le dans un répertoire, c'est home/scripts-à- dire et ajoutez ce répertoire à votre chemin dans ~/.bash_profileou dans un fichier similaire utilisé par le terminal.

# Custom scripts
export CUSTOM_SCRIPTS=home/scripts
export PATH=$CUSTOM_SCRIPTS:$PATH

Ensuite, créez un lien vers ce script python à l'intérieur home/scripts/login.py

ln -s ~/home/scripts/login.py ~/home/scripts/login

Fermez votre terminal, démarrez-en un nouveau, exécutez login

David Morton
la source
4

La requests.Session()solution a aidé à se connecter à un formulaire avec protection CSRF (tel qu'utilisé dans les formulaires Flask-WTF). Vérifiez si un csrf_tokenest requis comme champ caché et ajoutez-le à la charge utile avec le nom d'utilisateur et le mot de passe:

import requests
from bs4 import BeautifulSoup

payload = {
    'email': '[email protected]',
    'password': 'passw0rd'
}     

with requests.Session() as sess:
    res = sess.get(server_name + '/signin')
    signin = BeautifulSoup(res._content, 'html.parser')
    payload['csrf_token'] = signin.find('input', id='csrf_token')['value']
    res = sess.post(server_name + '/auth/login', data=payload)
Naaman
la source