Python'un İstekler modülünü kullanarak bir web sitesinde nasıl "oturum açılır"?


99

Python'daki Requests modülünü kullanarak bir web sitesine giriş yapmak için bir istek göndermeye çalışıyorum, ancak gerçekten çalışmıyor. Bu konuda yeniyim ... bu yüzden Kullanıcı Adı ve Parolamı tanımlama bilgileri mi yoksa bulduğum bir tür HTTP yetkilendirme şeyi mi yapmam gerektiğini anlayamıyorum (??).

from pyquery import PyQuery
import requests

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

Şimdi, "post" ve çerez kullanmam gerektiğini düşünüyorum ...

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

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

content = r.text

q = PyQuery(content)

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

print title

Kurabiye işini yanlış yaptığımı hissediyorum ... Bilmiyorum.

Doğru giriş yapmazsa, ana sayfanın başlığı "Locationary.com" a gelmeli ve varsa "Ana Sayfa" olmalıdır.

İstekler ve kurabiyeler hakkında bana birkaç şey açıklayabilir ve bu konuda bana yardımcı olabilirseniz, çok memnun olurum. : D

Teşekkürler.

... Hala gerçekten işe yaramadı. Tamam ... yani giriş yapmadan önce ana sayfadaki HTML'nin söylediği şey:

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

Bu yüzden doğru yaptığımı düşünüyorum, ancak çıktı hala "Locationary.com"

2. DÜZENLEME:

Uzun süre giriş yapmış kalabilmek istiyorum ve bu alan adı altında bir sayfa talep ettiğimde, içeriğin giriş yapmışım gibi görünmesini istiyorum.

Yanıtlar:


45

İstediğiniz bilgiler giriş yaptıktan hemen sonra yönlendirildiğiniz sayfada ise ...

Bunun yerine, python istekleri belgelerinde olduğu gibi ckdeğişkeninizi çağıralım :payload

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

Aksi takdirde...

Aşağıdaki https://stackoverflow.com/a/17633072/111362 adresine bakın.


Urllib, urrlib2 ve cookielib ve bazı HTTP Başlıkları kullanarak farklı bir şekilde çalışmasını sağladım.
Marcus Johnson

24
Maalesef bunu silemiyorum çünkü kabul edilen cevap bu. Bunu gönderdiğimde soruyu anladığımı sanmıyorum (daha sonra açıklandı), bu yüzden neden kabul edildiğinden emin değilim. Cevabım yalnızca ihtiyacınız olan veriler giriş yaptıktan sonra yönlendirildiğiniz sayfadaysa işe yarar. @tigerFinch'in çok daha iyi bir cevabı var.
katy lavallee

238

Başka bir çözüm bulduğunuzu biliyorum, ancak benim gibi bu soruyu bulan, aynı şeyi arayanlar için, aşağıdaki gibi isteklerle sağlanabilir:

İlk olarak, Marcus'un yaptığı gibi, üç parça bilgi almak için giriş formunun kaynağını kontrol edin - formun gönderdiği url ve kullanıcı adı ve şifre alanlarının ad özellikleri. Onun örneğinde, bunlar inUserName ve inUserPass.

Bunu aldıktan sonra requests.Session(), giriş bilgilerinizle birlikte bir yük olarak giriş url'sine bir gönderi isteği yapmak için bir örnek kullanabilirsiniz . Bir oturum örneğinden istekte bulunmak, temelde istekleri normal şekilde kullanmakla aynıdır, yalnızca kalıcılık katarak tanımlama bilgilerini depolamanıza ve kullanmanıza olanak tanır.

Oturum açma girişiminizin başarılı olduğunu varsayarsak, siteye başka isteklerde bulunmak için oturum örneğini kullanabilirsiniz. Sizi tanımlayan çerez, talepleri yetkilendirmek için kullanılacaktır.

Misal

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

13
Ancak soru şu, POST giriş formu nasıl alınır? Kullanıcı adı, KULLANICIADI vb. Değil de KullanıcıAdı mı çağrıldığını nasıl bilebilirim?
lsheng

4
@Twinkle, orada ne dediklerini görmek için formun HTML kaynağına bakın.
Aaron Schumacher

3
s.text işe yaramıyor gibi görünüyor, ama yine de bana isteklerle bu güzelliği gösterdiğiniz için size oy verme sevgisi veriyorum ... sözdizimi
Yazılım Peygamberleri

s.text çalışmıyor çünkü böyle bir şey olmalı: p = s.post('LOGIN_URL.....ve sonrap.text
Sebastian

2
@HalcyonAbrahamRamirez Burasının yardım aramanız için doğru yer olduğunu sanmıyorum. Sorunuzla ilgili özellikle şu soruları okumanızı öneririm: stackoverflow.com/questions/21928368/… ve eğer çözemezseniz kendi sorunuzu açın.
Sebastian

38

Bunu basitleştirmeye çalışayım, sitenin URL'sinin http://example.com/ olduğunu varsayalım ve kullanıcı adı ve şifre girerek kaydolmanız gerektiğini varsayalım, bu yüzden http: // example diyelim . com.tr / login.php şimdi ve kaynak kodunu görüntüleyin ve eylem URL'sini arayın, form etiketi gibi bir şey olacak

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

şimdi ' http://example.com/userinfo.php ' olacak mutlak URL yapmak için userinfo.php'yi alın , şimdi basit bir python betiği çalıştırın

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

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

Umarım bu bir gün birine yardımcı olur.


1
güzel bir - bazen ad / geçiş alanının öğesinin incelenmesinin düğme yerine çağrılan dosyayı açığa çıkarabileceğini unutmayın (benimki düğme incelemesinde 'eylem' dedi, url usr / pass alanlarını inceleyerek gösterildi)
baxx

2
Chrome kullanıyorsanız, ağ sekmesindeki devtools'u açın ve istekte bulunduktan sonra gerçek değerleri, hangi anahtarlarla ve nereye gönderildiklerini inceleyebilirsiniz, bu, geleneksel mekaniği kullanmayan formlar için yararlıdır ve bunun yerine formu işlemek için javascript / ajax kullanın.
Roberto Arosemena

1
bu durumda, sayfa içeriğini yazdırmak yerine web sayfasının nasıl doğrudan açılmasını sağlayacağınıza dair bir fikriniz var mı?

webbrowserModülü kullanmanız gerekecek
R. Barrett

Ayrıca yukarıdaki print r.contentyanlış da kullanıyor olmalıprint(r.content)
R. Barrett

6

Kullanıcı adları <...name=username.../>ve şifreler için web sitesi formunda kullanılan girişlerin adlarını bulun <...name=password../>ve aşağıdaki komut dosyasında değiştirin. Ayrıca, oturum açmak için istenen siteyi gösterecek şekilde URL'yi değiştirin.

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)

Kullanımı disable_warnings(InsecureRequestWarning)onaylanmamış SSL sertifikaları ile sitelere giriş çalışırken komut dosyasından herhangi bir çıktı kapatacaktır.

Ekstra:

Bu betiği UNIX tabanlı bir sistemde komut satırından çalıştırmak için bir dizine yerleştirin, yani home/scriptsbu dizini yolunuza ~/.bash_profileveya terminal tarafından kullanılan benzer bir dosyaya ekleyin .

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

Sonra içindeki bu python betiğine bir bağlantı oluşturun home/scripts/login.py

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

Terminalinizi kapatın, yeni bir tane başlatın, koşun login


4

requests.Session()Çözeltisi (şekilde Flask-wtf formlarında kullanılan) CSRF Koruma bir forma kaydı ile destekli. csrf_tokenBir gizli alan olarak gerekli olup olmadığını kontrol edin ve bunu kullanıcı adı ve şifre ile yüke ekleyin:

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)

0

Bazı sayfalar oturum açma / geçişten daha fazlasını gerektirebilir. Gizli alanlar bile olabilir. En güvenilir yol, hangi verilerin aktarıldığını görmek için inceleme aracını kullanmak ve oturum açarken ağ sekmesine bakmaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.