Làm cách nào để “đăng nhập” vào một trang web bằng mô-đun Yêu cầu của Python?


95

Tôi đang cố gắng đăng yêu cầu đăng nhập vào một trang web bằng mô-đun Yêu cầu bằng Python nhưng nó không thực sự hoạt động. Tôi là người mới làm quen với điều này ... vì vậy tôi không thể tìm ra liệu tôi có nên tạo cookie Tên người dùng và Mật khẩu của mình hay một số loại ủy quyền HTTP mà tôi đã tìm thấy (??).

from pyquery import PyQuery
import requests

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

Vì vậy, bây giờ, tôi nghĩ rằng tôi phải sử dụng "bài đăng" và 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

Tôi có cảm giác rằng tôi đang làm sai điều bánh quy ... Tôi không biết.

Nếu nó không đăng nhập chính xác, tiêu đề của trang chủ sẽ xuất hiện là "Locationary.com" và nếu có, nó sẽ là "Trang chủ".

Nếu bạn có thể giải thích một số điều về yêu cầu và cookie cho tôi và giúp tôi giải quyết vấn đề này, tôi sẽ đánh giá rất cao điều đó. : D

Cảm ơn.

... Nó vẫn chưa thực sự hoạt động. Được rồi ... đây là những gì HTML trang chủ nói trước khi bạn đăng nhập:

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

Vì vậy, tôi nghĩ mình đang làm đúng, nhưng đầu ra vẫn là "Locationary.com"

CHỈNH SỬA THỨ 2:

Tôi muốn có thể đăng nhập trong một thời gian dài và bất cứ khi nào tôi yêu cầu một trang trong tên miền đó, tôi muốn nội dung hiển thị như khi tôi đã đăng nhập.

Câu trả lời:


44

Nếu thông tin bạn muốn có trên trang bạn được chuyển đến ngay sau khi đăng nhập ...

Thay vào đó, hãy gọi ckbiến của bạn payload, như trong tài liệu python-request :

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

Nếu không thì...

Xem https://stackoverflow.com/a/17633072/111362 bên dưới.


Tôi đã làm cho nó hoạt động theo một cách khác bằng cách sử dụng urllib, urrlib2 và cookielib và một số tiêu đề HTTP.
Marcus Johnson

23
Rất tiếc, tôi không thể xóa điều này vì đó là câu trả lời được chấp nhận. Tôi không nghĩ rằng tôi đã hiểu câu hỏi khi tôi đăng bài này (nó đã được làm rõ sau đó), vì vậy không chắc tại sao nó được chấp nhận. Câu trả lời của tôi chỉ hoạt động nếu dữ liệu bạn cần nằm trên trang bạn được chuyển hướng đến sau khi đăng nhập. @tigerFinch có một câu trả lời hay hơn nhiều.
katy lavallee

228

Tôi biết bạn đã tìm thấy một giải pháp khác, nhưng đối với những người như tôi, những người tìm thấy câu hỏi này, đang tìm kiếm điều tương tự, nó có thể đạt được với các yêu cầu như sau:

Đầu tiên, như Marcus đã làm, hãy kiểm tra nguồn của biểu mẫu đăng nhập để lấy ba phần thông tin - url mà biểu mẫu đăng lên và các thuộc tính tên của trường tên người dùng và mật khẩu. Trong ví dụ của anh ấy, chúng là inUserName và inUserPass.

Khi bạn đã có điều đó, bạn có thể sử dụng một requests.Session()phiên bản để thực hiện yêu cầu đăng lên url đăng nhập với chi tiết đăng nhập của bạn dưới dạng tải trọng. Thực hiện các yêu cầu từ một phiên bản về cơ bản giống như việc sử dụng các yêu cầu thông thường, nó chỉ đơn giản là thêm tính bền bỉ, cho phép bạn lưu trữ và sử dụng cookie, v.v.

Giả sử nỗ lực đăng nhập của bạn thành công, bạn có thể chỉ cần sử dụng phiên bản để thực hiện các yêu cầu khác tới trang web. Cookie nhận dạng bạn sẽ được sử dụng để cho phép các yêu cầu.

Thí dụ

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
Tuy nhiên, câu hỏi đặt ra là, làm thế nào để có được biểu mẫu đăng nhập POST? Làm cách nào để biết nó được gọi là inUserName chứ không phải tên người dùng, USERNAME, v.v.?
lsheng

4
@Twinkle nhìn vào nguồn HTML của biểu mẫu để xem chúng được gọi là gì ở đó.
Aaron Schumacher

3
s.text dường như không làm việc, nhưng tôi vẫn đang đem lại cho bạn một số tình yêu bỏ phiếu cho thấy tôi đáng yêu này với yêu cầu ... cú pháp
Phần mềm tiên tri

s.text không làm việc vì nó phải được một cái gì đó như thế này: p = s.post('LOGIN_URL.....và sau đóp.text
Sebastian

2
@HalcyonAbrahamRamirez Tôi không nghĩ đây là nơi thích hợp để bạn tìm kiếm sự trợ giúp. Tôi khuyên bạn nên đọc câu hỏi về thử thách của bạn cụ thể như: stackoverflow.com/questions/21928368/… và nếu bạn không thể giải quyết nó, hãy mở câu hỏi của riêng bạn.
Sebastian

36

Hãy để tôi cố gắng làm cho nó đơn giản, giả sử URL của trang web là http://example.com/ và giả sử bạn cần đăng ký bằng cách điền tên người dùng và mật khẩu, vì vậy chúng tôi chuyển đến trang đăng nhập, nói rằng http: // example. com / login.php ngay bây giờ và xem mã nguồn của nó và tìm kiếm URL hành động, nó sẽ ở dạng thẻ biểu mẫu như thế nào

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

bây giờ sử dụng userinfo.php để tạo URL tuyệt đối sẽ là ' http://example.com/userinfo.php ', bây giờ hãy chạy một tập lệnh python đơn giản

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

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

Tôi hy vọng rằng điều này sẽ giúp ai đó ở đâu đó vào một ngày nào đó.


1
một điều tuyệt vời - lưu ý rằng đôi khi việc kiểm tra phần tử của trường tên / pass có thể tiết lộ tệp được gọi chứ không phải là nút (tôi vừa nói 'hành động' khi kiểm tra nút, url được hiển thị khi kiểm tra trường usr / pass)
baxx

2
Nếu bạn đang sử dụng chrome, hãy mở devtools trên tab mạng và sau khi thực hiện yêu cầu, bạn có thể kiểm tra các giá trị thực tế, với khóa nào và chúng được gửi đến đâu, điều này hữu ích cho các biểu mẫu không sử dụng cơ chế truyền thống và thay vào đó sử dụng javascript / ajax để xử lý biểu mẫu.
Roberto Arosemena

1
trong trường hợp này, bất kỳ ý tưởng nào về cách làm cho trang web bật lên trực tiếp thay vì in nội dung trang?

Bạn sẽ cần phải sử dụng webbrowsermô-đun
R. Barrett

Ngoài ra ở trên của anh ấy print r.contentlà sai, anh ấy nên sử dụngprint(r.content)
R. Barrett

6

Tìm tên của đầu vào được sử dụng trên biểu mẫu trang web cho tên người dùng <...name=username.../>và mật khẩu <...name=password../>và thay thế chúng trong tập lệnh bên dưới. Đồng thời thay thế URL để trỏ đến trang web mong muốn để đăng nhập.

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)

Việc sử dụng disable_warnings(InsecureRequestWarning)sẽ tắt mọi đầu ra từ tập lệnh khi cố gắng đăng nhập vào các trang web có chứng chỉ SSL chưa được xác minh.

Thêm:

Để chạy tập lệnh này từ dòng lệnh trên hệ thống dựa trên UNIX, hãy đặt nó vào một thư mục, tức là home/scriptsvà thêm thư mục này vào đường dẫn của bạn trong ~/.bash_profilehoặc một tệp tương tự được sử dụng bởi thiết bị đầu cuối.

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

Sau đó, tạo một liên kết đến tập lệnh python này bên trong home/scripts/login.py

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

Đóng thiết bị đầu cuối của bạn, bắt đầu một thiết bị mới, chạy login


4

Các requests.Session()giải pháp hỗ trợ với khai thác gỗ thành một dạng với bảo vệ CSRF (như được sử dụng trong các hình thức Flask-WTF). Kiểm tra xem csrf_tokencó phải là trường ẩn bắt buộc hay không và thêm trường đó vào tải trọng bằng tên người dùng và mật khẩu:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.