Python模擬京東登入(附完整程式碼)
來源:IMyxuan
連結:https://segmentfault.com/a/1190000011978866
分析登入的網路請求
開啟https://passport.jd.com/new/login.aspx
開啟瀏覽器的除錯面板,然後,輸入賬號密碼 =>> 登入,然後看除錯面板上面的Network捕捉到的網路請求,如下圖:
根據上面的圖片,我們可以知道,在我們點選完登入按鈕之後,瀏覽器傳送了一個POST請求到https://passport.jd.com/uc/loginService,然後在請求頭上面帶上了一些基本的引數,最重要的有三個,一個是cookie,一個是Referer,還有一個是User-Agent。
然後,再看看請求所需要的引數,這裡面有兩部分,一個是Query Params:
uuid:6a9ddda4-1819-4819-a888-b59301f83a59
ReturnUrl:https://item.jd.com/5089239.html
r: 0.2520828231526894
version: 2015
另一個是Form Data:
uuid:6a9ddda4-1819-4819-a888-b59301f83a59
eid:F37T4YRBOPZZ6JSEGDA7WH2VCIETQY…J23JGCTD3IM4TMK44Y5ATOTO6G4SM
fp:87783198d64a9aa25b3f0b28b152b094
_t:_t
loginType:f
loginname: [email protected]
nloginpwd:P+TbkVGbhhhC4DFlZ7y4az8j/Y1QYw…h0qs8+bKp7UbHeGWF1KEMrQUG5po=
chkRememberMe:
authcode:
pubKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNAD…woanQq+CA6agNkqly2H4j6wIDAQAB
sa_token: B68C442BE645754F33277E70120805…8EF504D2CD67D7341B8BFBA47FFA5
上面的引數裡面,基本可以在頁面上面可以找到
其中:ReturnUrl是登入成功後返回的頁面,authcode是圖片驗證碼,本例子上面不需要輸入驗證碼。
Python實現
根據上面的分析我們只需要通過程式碼傳送一個post請求,並且帶上相對應的引數就可以實現登入了。所有的引數,我們都可以輕而易舉地獲取,唯一的困難是cookie,但是,Python的requests庫給我們提供了會話機制,也就是requests.Session(),因此,具體的實現過程可以如程式碼所示。
完整程式碼
# -*- coding: UTF-8 -*-
import json
import requests
import sys
from bs4 import BeautifulSoup
s = requests.Session()
class JD:
def __init__(self, username, password):
self.username = username
self.password = password
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0',
'Referer': 'https://www.jd.com/'
}
def get_login_data(self):
url = 'https://passport.jd.com/new/login.aspx'
html = s.get(url, headers=self.headers).content
soup = BeautifulSoup(html, 'lxml')
display = soup.select('#o-authcode')[0].get('style')
auth_code = ''
if not display:
print('需要驗證碼。。。')
auth_code_url = soup.select('#JD_Verification1')[0].get('src2')
auth_code = self.get_auth_img(auth_code_url)
uuid = soup.select('#uuid')[0].get('value')
eid = soup.select('#eid')[0].get('value')
fp = soup.select('input[name="fp"]')[0].get('value') # session id
_t = soup.select('input[name="_t"]')[0].get('value') # token
login_type = soup.select('input[name="loginType"]')[0].get('value')
pub_key = soup.select('input[name="pubKey"]')[0].get('value')
sa_token = soup.select('input[name="sa_token"]')[0].get('value')
data = {
'uuid': uuid,
'eid': eid,
'fp': fp,
'_t': _t,
'loginType': login_type,
'loginname': self.username,
'nloginpwd': self.password,
'chkRememberMe': True,
'authcode': '',
'pubKey': pub_key,
'sa_token': sa_token,
'authCode': auth_code
}
return data
def get_auth_img(self, url):
auth_code_url = 'http:' + url
auth_img = s.get(auth_code_url, headers=self.headers)
with open(sys.path[0] + '/auth.jpg', 'wb') as f:
f.write(auth_img.content)
code = input('請輸入驗證碼:')
return code
def login(self):
"""
登入
:return:
"""
url = 'https://passport.jd.com/uc/loginService'
data = self.get_login_data()
headers = {
'Referer': 'https://passport.jd.com/uc/login?ltype=logout',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0',
'X-Requested-With': 'XMLHttpRequest'
}
content = s.post(url, data=data, headers=headers).text
result = json.loads(content[1: -1])
return result
def rush(self):
print('功能正在趕來的路上,敬請期待。。。')
pass
def handle():
print("*************** 選單列表 **************")
print('1、搶購')
print('2、加入購物車')
num = input('請輸入功能編號:')
if num == '1':
print('搶購功能正在趕來的路上,敬請期待。。。')
else:
print('加入購物車功能正在趕來的路上,敬請期待。。。')
# print('加入購物車成功!!!')
pass
username = input('請輸入京東賬號:')
password = input('請輸入京東密碼:')
jd = JD(username, password)
result = jd.login()
if result.get('success'):
print('登入成功')
handle()
else:
print('登入失敗')