使用 DrissionPage 实现京东登录及滑块验证

安装 DrissionPage

1
pip install drissionpage

编写代码

代码这里我们要实现的主要就是两个功能:

  1. 自动输入用户信息进行登录
  2. 自动操作滑块进行验证并通过

这里的难点就是滑块的轨迹生成,不过值得高兴的是,登录的这个滑块目前还没有轨迹验证,在后面的商品列表获取时出现的滑块验证才是难点。

代码

JdCrawler.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import random  
import time
import ddddocr
from DrissionPage import Chromium
from track import get_tracks


class JdCrawler:
"""
京东爬虫
"""
def __init__(self):
self.browser = Chromium()
self.tab = self.browser.latest_tab


def login(self):
self.tab.get('https://passport.jd.com/new/login.aspx?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F')
self.tab.ele('css:#loginname').input('your_jd_username')
self.tab.ele('css:#nloginpwd').input('your_jd_password')
self.tab.ele('css:#loginsubmit').click()

self.tab.wait.doc_loaded()
time.sleep(1)

self.verify_login_slider()

def verify_login_slider(self):
# 1.获取滑块图片
background_bytes = self.tab.ele('css:.JDJRV-bigimg img').src()
cut_bytes = self.tab.ele('css:.JDJRV-smallimg img').src()
# 2.识别滑块缺口并获取滑动轨迹
det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
result = det.slide_match(cut_bytes, background_bytes, simple_target=True)
print("滑块距离", result)
offset = result['target'][0]

# 拖动的按钮
move_img = self.tab.ele('css:.JDJRV-slide-btn')
# 开始拖动
self.tab.actions.hold(move_img)
tracks = get_tracks(offset * 342 / 360) # 342/360 为背景图片的实际宽度和渲染宽度之比
print("轨迹", tracks)
# 向前滑动
for track in tracks['move_list']:
self.tab.actions.move(offset_x=track, offset_y=random.uniform(-7.5, 10.5),
duration=random.uniform(0.01, 0.05))

self.tab.actions.release(move_img)
time.sleep(1)
if self.tab.ele('css:#JDJRV-wrap-loginsubmit').style('display') != 'none':
print("滑块验证失败,重新验证")
self.verify_login_slider()
else:
print("滑块验证通过")
return True


if __name__ == '__main__':
jd = JdCrawler()
jd.login()

track.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def get_tracks(distance):  
"""滑块运动轨迹"""
value = round(random.uniform(0.55, 0.75), 2)
v, t, sum1 = 0, 0.3, 0
plus = []
mid = distance * value
while sum1 < distance:
if sum1 < mid:
a = round(random.uniform(2.5, 3.5), 1)
else:
a = -round(random.uniform(2.0, 3.5), 1)
s = v * t + 0.5 * a * (t ** 2)
v = v + a * t
sum1 += s
plus.append(round(s))
return {"move_list": plus}