Wie melde ich mich mit dem Python-Modul "Anfragen" bei einer Website an?

95

Ich versuche, eine Anfrage zum Anmelden auf einer Website mit dem Modul "Anfragen" in Python zu veröffentlichen, aber es funktioniert nicht wirklich. Ich bin neu in diesem Bereich ... daher kann ich nicht herausfinden, ob ich meine Benutzernamen- und Kennwort-Cookies oder eine von mir gefundene HTTP-Autorisierungssache (??) erstellen soll.

from pyquery import PyQuery
import requests

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

Jetzt denke ich, ich sollte "Post" und Cookies verwenden ...

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

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

content = r.text

q = PyQuery(content)

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

print title

Ich habe das Gefühl, dass ich die Kekse falsch mache ... ich weiß es nicht.

Wenn es sich nicht richtig anmeldet, sollte der Titel der Homepage auf "Locationary.com" erscheinen, und wenn dies der Fall ist, sollte es "Homepage" sein.

Wenn Sie mir vielleicht ein paar Dinge über Anfragen und Cookies erklären und mir dabei helfen könnten, wäre ich Ihnen sehr dankbar. : D.

Vielen Dank.

... Es hat immer noch nicht wirklich funktioniert. Okay ... das sagt der HTML-Code der Startseite, bevor Sie sich anmelden:

</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>

Ich denke, ich mache es richtig, aber die Ausgabe ist immer noch "Locationary.com".

2. EDIT:

Ich möchte in der Lage sein, lange angemeldet zu bleiben, und wenn ich eine Seite unter dieser Domain anfordere, möchte ich, dass der Inhalt so angezeigt wird, als wäre ich angemeldet.

Marcus Johnson
quelle

Antworten:

44

Wenn sich die gewünschten Informationen auf der Seite befinden, zu der Sie unmittelbar nach der Anmeldung weitergeleitet werden ...

Rufen wir stattdessen Ihre ckVariable auf payload, wie in den Python-Anforderungsdokumenten :

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

Andernfalls...

Siehe https://stackoverflow.com/a/17633072/111362 unten.

katy lavallee
quelle
Ich habe es dazu gebracht, mit urllib, urrlib2 und cookielib und einigen HTTP-Headern anders zu arbeiten.
Marcus Johnson
23
Leider kann ich dies nicht löschen, da es die akzeptierte Antwort ist. Ich glaube nicht, dass ich die Frage verstanden habe, als ich sie gepostet habe (sie wurde später geklärt), also nicht sicher, warum sie akzeptiert wird. Meine Antwort funktioniert nur, wenn sich die benötigten Daten auf der Seite befinden, zu der Sie nach der Anmeldung weitergeleitet werden. @tigerFinch hat eine viel bessere Antwort.
Katy Lavallee
227

Ich weiß, dass Sie eine andere Lösung gefunden haben, aber für diejenigen wie mich, die diese Frage finden und dasselbe suchen, kann dies mit folgenden Anfragen erreicht werden:

Überprüfen Sie zunächst wie Marcus die Quelle des Anmeldeformulars, um drei Informationen zu erhalten - die URL, an die das Formular gesendet wird, und die Namensattribute der Felder Benutzername und Kennwort. In seinem Beispiel sind dies inUserName und inUserPass.

Sobald Sie das haben, können Sie eine requests.Session()Instanz verwenden, um eine Post-Anfrage an die Login-URL mit Ihren Login-Daten als Nutzdaten zu senden. Das Erstellen von Anforderungen aus einer Sitzungsinstanz entspricht im Wesentlichen der normalen Verwendung von Anforderungen. Es erhöht lediglich die Persistenz und ermöglicht das Speichern und Verwenden von Cookies usw.

Angenommen, Ihr Anmeldeversuch war erfolgreich, können Sie einfach die Sitzungsinstanz verwenden, um weitere Anforderungen an die Site zu stellen. Das Cookie, das Sie identifiziert, wird zum Autorisieren der Anforderungen verwendet.

Beispiel

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...
tigerFinch
quelle
12
Die Frage ist jedoch, wie man das POST-Anmeldeformular erhält. Wie kann ich wissen, ob es inUserName statt Benutzername, USERNAME usw. heißt?
lsheng
4
@ Twinkle Schauen Sie in der HTML-Quelle nach dem Formular, um zu sehen, wie sie dort heißen.
Aaron Schumacher
3
s.text scheint nicht zu funktionieren, aber ich gebe Ihnen immer noch eine gewisse Liebe, um mir diese schöne mit Anfragen zu zeigen ... Syntax
Software Prophets
s.text funktioniert nicht, weil es so etwas sein sollte: p = s.post('LOGIN_URL.....und dannp.text
Sebastian
2
@HalcyonAbrahamRamirez Ich glaube nicht, dass dies der richtige Ort für Sie ist, um Hilfe zu suchen. Ich schlage vor, die Frage über Ihre Herausforderung speziell zu lesen : stackoverflow.com/questions/21928368/… und wenn Sie sie nicht lösen können, öffnen Sie Ihre eigene Frage.
Sebastian
36

Lassen Sie mich versuchen, es einfach zu machen. Angenommen, die URL der Website lautet http://example.com/. Angenommen, Sie müssen sich anmelden, indem Sie Benutzername und Passwort eingeben. Gehen Sie also zur Anmeldeseite und sagen Sie http: // Beispiel. com / login.php jetzt und sehen Sie sich den Quellcode an und suchen Sie nach der Aktions-URL, die in Form eines Tags vorliegen soll

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

Nehmen Sie jetzt userinfo.php, um eine absolute URL zu erstellen, die " http://example.com/userinfo.php " lautet. Führen Sie nun ein einfaches Python-Skript aus

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

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

Ich hoffe, dass dies irgendwann jemandem irgendwo hilft.

Tarun Venugopal Nair
quelle
1
Nettes - beachten Sie, dass beim Überprüfen des Elements des Felds name / pass manchmal die aufgerufene Datei und nicht die Schaltfläche angezeigt wird (meine hat bei der Überprüfung der Schaltfläche nur "Aktion" gesagt, die URL wurde beim Überprüfen der Felder usr / pass
angezeigt
2
Wenn Sie Chrome verwenden, öffnen Sie die devtools auf der Registerkarte "Netzwerk". Nach der Anforderung können Sie die tatsächlichen Werte überprüfen, mit welchen Schlüsseln und wohin sie gesendet wurden. Dies ist nützlich für Formulare, die keine herkömmliche Mechanik verwenden Verwenden Sie Javascript / Ajax, um das Formular zu verarbeiten.
Roberto Arosemena
1
In diesem Fall eine Idee, wie die Webseite direkt angezeigt werden kann, anstatt den Seiteninhalt zu drucken?
Sie müssen das webbrowserModul verwenden
R. Barrett
Auch sein obiges print r.contentist falsch, das er verwenden sollteprint(r.content)
R. Barrett
6

Finden Sie den Namen der Eingaben heraus, die auf dem Website-Formular für Benutzernamen <...name=username.../>und Kennwörter verwendet werden, <...name=password../>und ersetzen Sie sie im folgenden Skript. Ersetzen Sie auch die URL, um auf die gewünschte Site zu verweisen, bei der Sie sich anmelden möchten.

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)

Durch die Verwendung von disable_warnings(InsecureRequestWarning)werden alle Ausgaben des Skripts stummgeschaltet, wenn versucht wird, sich bei Sites mit nicht verifizierten SSL-Zertifikaten anzumelden.

Extra:

Um dieses Skript über die Befehlszeile auf einem UNIX-basierten System auszuführen, legen Sie es in einem Verzeichnis ab, dh home/scriptsfügen Sie dieses Verzeichnis Ihrem Pfad in ~/.bash_profileoder einer ähnlichen Datei hinzu, die vom Terminal verwendet wird.

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

Erstellen Sie dann einen Link zu diesem Python-Skript home/scripts/login.py

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

Schließen Sie Ihr Terminal, starten Sie ein neues und führen Sie es aus login

David Morton
quelle
4

Die requests.Session()Lösung unterstützte die Anmeldung in einem Formular mit CSRF-Schutz (wie in Flask-WTF-Formularen verwendet). Überprüfen Sie, ob a csrf_tokenals verstecktes Feld erforderlich ist, und fügen Sie es mit dem Benutzernamen und dem Kennwort zur Nutzlast hinzu:

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
quelle