Come "accedere" a un sito Web utilizzando il modulo Richieste di Python?


95

Sto cercando di inviare una richiesta per accedere a un sito Web utilizzando il modulo Richieste in Python ma non funziona davvero. Sono nuovo a questo ... quindi non riesco a capire se devo fare i miei cookie per nome utente e password o qualche tipo di autorizzazione HTTP che ho trovato (??).

from pyquery import PyQuery
import requests

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

Quindi ora, penso che dovrei usare "post" e cookie ....

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

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

content = r.text

q = PyQuery(content)

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

print title

Ho la sensazione di sbagliare con i biscotti ... Non lo so.

Se non si accede correttamente, il titolo della home page dovrebbe essere "Locationary.com" e se lo fa, dovrebbe essere "Home Page".

Se potessi spiegarmi alcune cose su richieste e cookie e aiutarmi con questo, lo apprezzerei molto. : D

Grazie.

... Ancora non funzionava ancora. Ok ... quindi questo è ciò che dice l'HTML della home page prima di accedere:

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

Quindi penso di farlo bene, ma l'output è ancora "Locationary.com"

2a EDIT:

Voglio essere in grado di rimanere connesso per molto tempo e ogni volta che richiedo una pagina sotto quel dominio, voglio che il contenuto appaia come se fossi loggato.

Risposte:


44

Se le informazioni desiderate si trovano nella pagina a cui vieni indirizzato subito dopo il login ...

Chiamiamo invece la tua ckvariabile payload, come nei documenti di richieste python :

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

Altrimenti...

Vedi https://stackoverflow.com/a/17633072/111362 di seguito.


Ho fatto in modo che funzionasse in modo diverso utilizzando urllib, urrlib2 e cookielib e alcuni header HTTP.
Marcus Johnson

23
Purtroppo non posso eliminarlo perché è la risposta accettata. Non credo di aver capito la domanda quando l'ho postata (è stata chiarita dopo), quindi non sono sicuro del motivo per cui è stata accettata. La mia risposta funziona solo se i dati di cui hai bisogno si trovano nella pagina a cui vieni reindirizzato dopo il login. @tigerFinch ha una risposta molto migliore.
katy lavallee

228

So che hai trovato un'altra soluzione, ma per chi come me trova questa domanda, cercando la stessa cosa, si può ottenere con richieste come segue:

In primo luogo, come ha fatto Marcus, controlla l'origine del modulo di accesso per ottenere tre informazioni: l'URL a cui il modulo invia e gli attributi del nome dei campi nome utente e password. Nel suo esempio, sono inUserName e inUserPass.

Dopo averlo ottenuto, puoi utilizzare requests.Session()un'istanza per effettuare una richiesta di post all'URL di accesso con i tuoi dettagli di accesso come payload. Effettuare richieste da un'istanza di sessione è essenzialmente la stessa cosa che utilizzare normalmente le richieste, aggiunge semplicemente persistenza, consentendo di memorizzare e utilizzare i cookie, ecc.

Supponendo che il tuo tentativo di accesso abbia avuto esito positivo, puoi semplicemente utilizzare l'istanza della sessione per effettuare ulteriori richieste al sito. Il cookie che ti identifica verrà utilizzato per autorizzare le richieste.

Esempio

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

12
La domanda è, tuttavia, come ottenere il modulo di login POST? Come posso sapere se si chiama inUserName anziché username, USERNAME ecc.?
lsheng

4
@Twinkle guarda il sorgente HTML del modulo per vedere come vengono chiamati lì.
Aaron Schumacher

3
s. il testo non sembra funzionare, ma ti sto ancora dando un po 'di amore per avermi mostrato questo adorabile con richieste ... sintassi
Software Prophets

s.text non funziona perché dovrebbe essere qualcosa del genere: p = s.post('LOGIN_URL.....e poip.text
Sebastian

2
@HalcyonAbrahamRamirez Non credo che questo sia il posto giusto per te per cercare aiuto. Suggerisco di leggere la domanda sulla tua sfida in particolare come: stackoverflow.com/questions/21928368/… e se non riesci a risolverla apri la tua domanda.
Sebastian

36

Vorrei provare a renderlo semplice, supponiamo che l'URL del sito sia http://example.com/ e supponiamo che tu debba registrarti inserendo nome utente e password, quindi andiamo alla pagina di accesso dicendo http: // esempio. com / login.php ora e visualizza il suo codice sorgente e cerca l'URL dell'azione che sarà nel tag del modulo qualcosa di simile

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

ora prendi userinfo.php per creare un URL assoluto che sarà ' http://example.com/userinfo.php ', ora esegui un semplice script python

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

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

Spero che questo aiuti qualcuno da qualche parte un giorno.


1
bella - nota che a volte l'ispezione dell'elemento del campo name / pass potrebbe rivelare il file chiamato piuttosto che il pulsante (il mio ha appena detto 'action' nell'ispezione del pulsante, l'URL è stato mostrato dall'ispezione dei campi usr / pass)
baxx

2
Se stai usando chrome, apri i devtools nella scheda di rete e dopo aver effettuato la richiesta puoi ispezionare i valori effettivi, con quali chiavi e dove sono stati inviati, questo è utile per i moduli che non utilizzano la meccanica tradizionale e invece usa javascript / ajax per elaborare il modulo.
Roberto Arosemena

1
in questo caso qualche idea su come far apparire la pagina web direttamente invece di stampare il contenuto della pagina?

Dovrai usare il webbrowsermodulo
R. Barrett

Anche il suo sopra print r.contentè sbagliato che dovrebbe usareprint(r.content)
R. Barrett

6

Scopri il nome degli input utilizzati nel modulo dei siti web per nomi utente <...name=username.../>e password <...name=password../>e sostituiscili nello script sottostante. Sostituisci anche l'URL in modo che punti al sito a cui desideri accedere.

login.py

#!/usr/bin/env python

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

L'utilizzo di disable_warnings(InsecureRequestWarning)silenzia qualsiasi output dello script quando si tenta di accedere a siti con certificati SSL non verificati.

Extra:

Per eseguire questo script dalla riga di comando su un sistema basato su UNIX, posizionalo in una directory, ad es. home/scriptsE aggiungi questa directory al tuo percorso ~/.bash_profileo un file simile utilizzato dal terminale.

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

Quindi crea un collegamento a questo script Python all'interno home/scripts/login.py

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

Chiudi il tuo terminale, avviane uno nuovo, corri login


4

La requests.Session()soluzione aiutava ad accedere a un modulo con protezione CSRF (come utilizzato nei moduli Flask-WTF). Controlla se csrf_tokenè richiesto un campo nascosto e aggiungilo al payload con nome utente e password:

import requests
from bs4 import BeautifulSoup

payload = {
    'email': 'email@example.com',
    '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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.