Bagaimana cara "masuk" ke situs web menggunakan modul Permintaan Python?

98

Saya mencoba mengirim permintaan untuk masuk ke situs web menggunakan modul Permintaan dengan Python tetapi tidak benar-benar berfungsi. Saya baru dalam hal ini ... jadi saya tidak tahu apakah saya harus membuat cookie Nama Pengguna dan Kata Sandi saya atau semacam otorisasi HTTP yang saya temukan (??).

from pyquery import PyQuery
import requests

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

Jadi sekarang, saya pikir saya harus menggunakan "pos" dan 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

Saya merasa bahwa saya melakukan kesalahan cookie ... Saya tidak tahu.

Jika tidak masuk dengan benar, judul beranda harus keluar ke "Locationary.com" dan jika ya, itu harus menjadi "Halaman Beranda."

Jika Anda mungkin dapat menjelaskan beberapa hal tentang permintaan dan cookie kepada saya dan membantu saya dalam hal ini, saya akan sangat menghargainya. : D

Terima kasih.

... Ini masih belum benar-benar berhasil. Oke ... jadi inilah yang dikatakan halaman beranda HTML sebelum Anda masuk:

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

Jadi menurut saya saya melakukannya dengan benar, tetapi hasilnya tetap "Locationary.com"

EDIT ke-2:

Saya ingin tetap masuk untuk waktu yang lama dan setiap kali saya meminta laman di bawah domain itu, saya ingin konten muncul seolah-olah saya sedang masuk.

Marcus Johnson
sumber

Jawaban:

44

Jika informasi yang Anda inginkan ada di halaman tempat Anda diarahkan segera setelah login ...

Mari panggil ckvariabel Anda payloadsebagai gantinya, seperti di dokumen python-request :

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

Jika tidak...

Lihat https://stackoverflow.com/a/17633072/111362 di bawah.

katy lavallee
sumber
Saya membuatnya bekerja dengan cara yang berbeda menggunakan urllib, urrlib2, dan cookielib dan beberapa HTTP Header.
Marcus Johnson
23
Sayangnya saya tidak dapat menghapus ini karena itu jawaban yang diterima. Saya rasa saya tidak mengerti pertanyaan ketika saya memposting ini (diklarifikasi setelahnya), jadi tidak yakin mengapa itu diterima. Jawaban saya hanya berfungsi jika data yang Anda butuhkan ada di halaman tempat Anda dialihkan setelah login. @tigerFinch memiliki jawaban yang jauh lebih baik.
katy lavallee
230

Saya tahu Anda telah menemukan solusi lain, tetapi bagi mereka yang seperti saya yang menemukan pertanyaan ini, mencari hal yang sama, dapat dicapai dengan permintaan sebagai berikut:

Pertama, seperti yang dilakukan Marcus, periksa sumber formulir login untuk mendapatkan tiga informasi - url tempat formulir dikirim, dan atribut nama bidang nama pengguna dan kata sandi. Dalam contohnya, mereka adalah inUserName dan inUserPass.

Setelah Anda mendapatkannya, Anda dapat menggunakan sebuah requests.Session()instance untuk membuat permintaan posting ke url login dengan rincian login Anda sebagai muatan. Membuat permintaan dari instance sesi pada dasarnya sama dengan menggunakan permintaan biasanya, ini hanya menambahkan ketekunan, memungkinkan Anda untuk menyimpan dan menggunakan cookie, dll.

Dengan asumsi upaya login Anda berhasil, Anda dapat menggunakan instance sesi untuk membuat permintaan lebih lanjut ke situs. Cookie yang mengidentifikasi Anda akan digunakan untuk mengotorisasi permintaan.

Contoh

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
sumber
13
Pertanyaannya adalah, bagaimana cara mendapatkan formulir login POST? Bagaimana saya bisa tahu jika itu disebut inUserName daripada username, USERNAME dll?
lsheng
4
@Twinkle lihat sumber HTML formulir untuk melihat apa namanya di sana.
Aaron Schumacher
3
s.text tampaknya tidak berfungsi, tetapi saya masih memberi Anda beberapa cinta voting untuk menunjukkan kepada saya yang indah ini dengan permintaan ... sintaks
Software Prophets
s.text tidak berfungsi karena seharusnya seperti ini: p = s.post('LOGIN_URL.....dan kemudianp.text
Sebastian
2
@HalcyonAbrahamRamirez Menurut saya ini bukan tempat yang tepat untuk mencari bantuan. Saya sarankan membaca pertanyaan tentang tantangan Anda secara khusus seperti: stackoverflow.com/questions/21928368/… dan jika Anda tidak dapat menyelesaikannya, buka pertanyaan Anda sendiri.
Sebastian
36

Biarkan saya mencoba membuatnya sederhana, misalkan URL situsnya adalah http://example.com/ dan misalkan Anda perlu mendaftar dengan mengisi nama pengguna dan kata sandi, jadi kita pergi ke halaman login katakan http: // contoh. com / login.php sekarang dan lihat kode sumbernya dan cari URL tindakan itu akan dalam bentuk tag seperti

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

sekarang ambil userinfo.php untuk membuat URL absolut yang akan menjadi ' http://example.com/userinfo.php ', sekarang jalankan skrip python sederhana

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

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

Saya harap ini membantu seseorang di suatu tempat suatu hari nanti.

Tarun Venugopal Nair
sumber
1
bagus satu - perhatikan bahwa kadang-kadang memeriksa elemen bidang nama / sandi mungkin mengungkapkan file yang dipanggil daripada tombol (saya hanya mengatakan 'tindakan' pada pemeriksaan tombol, url ditampilkan dari memeriksa bidang usr / pass)
baxx
2
Jika Anda menggunakan chrome, buka devtools di tab jaringan dan setelah membuat permintaan Anda dapat memeriksa nilai sebenarnya, dengan kunci apa dan ke mana kunci itu dikirim, ini berguna untuk formulir yang tidak menggunakan mekanisme tradisional dan sebagai gantinya gunakan javascript / ajax untuk memproses formulir.
Roberto Arosemena
1
dalam hal ini ada ide tentang cara membuat halaman web muncul langsung daripada mencetak konten halaman?
Anda perlu menggunakan webbrowsermodul
R. Barrett
Juga di atas print r.contentsalah dia harus menggunakanprint(r.content)
R. Barrett
6

Cari tahu nama input yang digunakan pada formulir situs web untuk nama pengguna <...name=username.../>dan kata sandi <...name=password../>dan ganti dalam skrip di bawah ini. Juga ganti URL untuk menunjuk ke situs yang diinginkan untuk masuk.

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)

Penggunaan dari disable_warnings(InsecureRequestWarning)akan membungkam keluaran apa pun dari skrip saat mencoba masuk ke situs dengan sertifikat SSL yang belum diverifikasi.

Tambahan:

Untuk menjalankan skrip ini dari baris perintah pada sistem berbasis UNIX, letakkan di direktori, yaitu home/scriptsdan tambahkan direktori ini ke jalur Anda di ~/.bash_profileatau file serupa yang digunakan oleh terminal.

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

Kemudian buat tautan ke skrip python ini di dalamnya home/scripts/login.py

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

Tutup terminal Anda, mulai yang baru, jalankan login

David Morton
sumber
4

The requests.Session()solusi dibantu dengan logging menjadi bentuk dengan Perlindungan CSRF (seperti yang digunakan dalam bentuk Flask-WTF). Periksa apakah csrf_tokendiperlukan sebagai bidang tersembunyi dan tambahkan ke payload dengan nama pengguna dan kata sandi:

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
sumber