¿Cómo "iniciar sesión" en un sitio web utilizando el módulo de solicitudes de Python?

95

Estoy tratando de publicar una solicitud para iniciar sesión en un sitio web utilizando el módulo Solicitudes en Python, pero en realidad no funciona. Soy nuevo en esto ... así que no puedo averiguar si debo hacer mis cookies de nombre de usuario y contraseña o algún tipo de autorización HTTP que encontré (??).

from pyquery import PyQuery
import requests

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

Entonces, creo que se supone que debo usar "publicación" y 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

Tengo la sensación de que estoy haciendo mal las galletas ... No lo sé.

Si no inicia sesión correctamente, el título de la página de inicio debería aparecer como "Locationary.com" y si lo hace, debería ser "Página de inicio".

Si pudiera explicarme algunas cosas sobre las solicitudes y las cookies y ayudarme con esto, se lo agradecería enormemente. :RE

Gracias.

... Todavía no funcionaba realmente. Bien ... esto es lo que dice el HTML de la página de inicio antes de iniciar sesión:

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

Creo que lo estoy haciendo bien, pero el resultado sigue siendo "Locationary.com".

2da EDICIÓN:

Quiero poder permanecer conectado durante mucho tiempo y cada vez que solicito una página bajo ese dominio, quiero que el contenido se muestre como si estuviera conectado.

Marcus Johnson
fuente

Respuestas:

44

Si la información que desea está en la página a la que se le dirige inmediatamente después de iniciar sesión ...

En su lugar, llamemos a su ckvariable payload, como en los documentos de solicitudes de python :

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

De otra manera...

Consulte https://stackoverflow.com/a/17633072/111362 a continuación.

katy lavallee
fuente
Hice que funcionara de una manera diferente usando urllib, urrlib2 y cookielib y algunos encabezados HTTP.
Marcus Johnson
23
Lamentablemente, no puedo eliminar esto porque es la respuesta aceptada. No creo que entendí la pregunta cuando publiqué esto (se aclaró después), así que no estoy seguro de por qué se acepta. Mi respuesta solo funciona si los datos que necesita están en la página a la que se le redirige después de iniciar sesión. @tigerFinch tiene una respuesta mucho mejor.
Katy Lavallee
228

Sé que ha encontrado otra solución, pero para aquellos como yo que encuentran esta pregunta, buscando lo mismo, se puede lograr con solicitudes de la siguiente manera:

En primer lugar, como hizo Marcus, verifique la fuente del formulario de inicio de sesión para obtener tres datos: la URL en la que se publica el formulario y los atributos de nombre de los campos de nombre de usuario y contraseña. En su ejemplo, son inUserName e inUserPass.

Una vez que lo tenga, puede usar un requests.Session() instancia para realizar una solicitud de publicación a la URL de inicio de sesión con sus datos de inicio de sesión como carga útil. Hacer solicitudes desde una instancia de sesión es esencialmente lo mismo que usar solicitudes normalmente, simplemente agrega persistencia, lo que le permite almacenar y usar cookies, etc.

Suponiendo que su intento de inicio de sesión fue exitoso, simplemente puede usar la instancia de sesión para realizar más solicitudes al sitio. La cookie que lo identifica se utilizará para autorizar las solicitudes.

Ejemplo

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
fuente
12
Sin embargo, la pregunta es cómo obtener el formulario de inicio de sesión POST. ¿Cómo puedo saber si se llama inUserName en lugar de username, USERNAME, etc.?
lsheng
4
@Twinkle mira la fuente HTML del formulario para ver cómo se llaman allí.
Aaron Schumacher
3
s.text no parece funcionar, pero todavía le estoy dando un poco de amor por mostrarme este hermoso con solicitudes ... sintaxis
Software Prophets
s.text no funciona porque debería ser algo como esto: p = s.post('LOGIN_URL.....y luegop.text
Sebastián
2
@HalcyonAbrahamRamirez No creo que este sea el lugar adecuado para buscar ayuda. Sugiero leer la pregunta sobre su desafío específicamente como: stackoverflow.com/questions/21928368/… y si no puede resolverlo, abra su propia pregunta.
Sebastian
36

Permítanme intentar hacerlo simple, supongamos que la URL del sitio es http://example.com/ y supongamos que necesita registrarse completando el nombre de usuario y la contraseña, por lo que vamos a la página de inicio de sesión, digamos http: // ejemplo. com / login.php ahora y vea su código fuente y busque la URL de acción, estará en la etiqueta de formulario algo como

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

ahora tome userinfo.php para hacer una URL absoluta que será ' http://example.com/userinfo.php ', ahora ejecute un script de Python simple

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

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

Espero que esto ayude a alguien en algún lugar algún día.

Tarun Venugopal Nair
fuente
1
uno agradable: tenga en cuenta que a veces inspeccionar el elemento del campo de nombre / contraseña puede revelar el archivo llamado en lugar del botón (el mío acaba de decir 'acción' en la inspección del botón, la URL se mostró al inspeccionar los campos usr / pass)
baxx
2
Si está usando Chrome, abra devtools en la pestaña de red y después de realizar la solicitud puede inspeccionar los valores reales, con qué claves y a dónde se enviaron, esto es útil para formularios que no usan mecánicas tradicionales y en su lugar use javascript / ajax para procesar el formulario.
Roberto Arosemena
1
en este caso, ¿alguna idea sobre cómo hacer que la página web aparezca directamente en lugar de imprimir el contenido de la página?
Deberá usar el webbrowsermódulo
R. Barrett
También su anterior print r.contentes equivocado que debe utilizarprint(r.content)
R. Barrett
6

Descubra el nombre de las entradas utilizadas en el formulario de sitios web para nombres de usuario <...name=username.../>y contraseñas <...name=password../>y reemplácelas en el siguiente script. También reemplace la URL para que apunte al sitio deseado para iniciar sesión.

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)

El uso de disable_warnings(InsecureRequestWarning)silenciará cualquier salida del script cuando intente iniciar sesión en sitios con certificados SSL no verificados.

Extra:

Para ejecutar este script desde la línea de comandos en un sistema basado en UNIX, colóquelo en un directorio, es decir, home/scriptsagregue este directorio a su ruta en ~/.bash_profileo un archivo similar utilizado por la terminal.

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

Luego crea un enlace a este script de Python dentro home/scripts/login.py

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

Cierra tu terminal, inicia una nueva, ejecuta login

David Morton
fuente
4

los requests.Session() solución ayudó a iniciar sesión en un formulario con CSRF Protection (como se usa en los formularios Flask-WTF). Compruebe si csrf_tokense requiere un campo oculto y agréguelo a la carga útil con el nombre de usuario y la contraseña:

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)
naamán
fuente