京东表示很无奈,爬虫都用它练手
登录时,浏览器发送了一个POST请求,在请求头上带了基本参数,并不是所有参数在模拟时都需要,一般需要cookie,Referer,和User-Agent
会话对象requests.Session能够跨请求地保持某些参数,比如cookies,即在同一个Session实例发出的所有请求都保持同一个cookies,而requests模块每次会自动处理cookies,这样就很方便地处理登录时的cookies问题。
如果header中包含用户cookie的话,不需用户名密码即可登录,可绕过验证码问题
源码返回json响应值,‘success’。copy的时候发现这里result返回值为整个页面str代码,并不是json响应,所以及其暴力地用find(‘我的订单’)判断
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 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
'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') # lxml HTML 解析器
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 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
content = s.post(url, data=data, headers=headers).text
json_string=json.dumps(content[1: -1])
result = json.loads(json_string)
return result
def rush(self):
print('功能正在赶来的路上,敬请期待。。。')
pass
def handle():
print("******************** 菜单列表 ********************")
print('1、抢购')
print('2、加入购物车')
num = input('请输入功能编号:')
if num == '1':
print('抢购功能还没做233')
elif num == '2':
print('加入购物车功能还没做233')
else:
print('你不按套路出牌啊')
pass
username = input('请输入京东账号(邮箱/手机号):')
password = input('请输入京东密码:')
jd = JD(username, password)
result = jd.login()
if result.find('我的订单') > 0:
print('登录成功')
handle()
else:
print('登录失败')
京东的登录,在第一次其认为有安全风险问题时,才会出现验证码,这里之后的登录均没有用到验证码。
参考资料
bs4 select()用法
python执行json.loads()错误及解决办法
BeautifulSoup用法
Python中Json库loads方法ValueError异常分析
python 中json库的 对象转换问题
读写json数据
Python模拟登录request.session()应用