1 ''''''
2 '''
3 破解极验滑动验证
4 破解极验滑动验证
5 博客园登录url:
6 https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F
7
8 代码逻辑:
9 1、输入用户名与密码,并点击登录
10 2、弹出滑动验证,获取有缺口与完整的图片
11 3、通过像素点进行比对,获取滑动位移距离
12 4、模拟人的行为轨迹
13 5、开始滑动
14
15 '''
16 from selenium import webdriver # 用来驱动浏览器的
17 from selenium.webdriver import ActionChains # 破解滑动验证码的时候用的 可以拖动图片
18 import time
19 from PIL import Image # pip3 install pillow
20 import random
21
22 # 截图图片函数
23 def cut_image(driver):
24 # 获取整个页面图片,图片名字为'snap.png'
25 driver.save_screenshot('snap.png')
26
27 # 获取滑动小画图
28 image = driver.find_element_by_class_name('geetest_canvas_img')
29 print(image.location)
30 print(image.size)
31
32 # 获取小图片的左上右下的位置
33 left = image.location['x']
34 top = image.location['y']
35 right = left + image.size['width']
36 buttom = top + image.size['height']
37 print(left, top, right, buttom)
38
39 # 调用open方法打开全屏图片并赋值给image_obj对象
40 image_obj = Image.open('snap.png')
41
42 # 通过image_obj对象对小图片进行截取
43 # box: The crop rectangle, as a (left, upper, right, lower)-tuple.
44 img = image_obj.crop((left, top, right, buttom))
45 # 打开截取后的小图片
46 # img.show()
47 return img
48
49 # 获取完整图片
50 def get_image1(driver):
51 time.sleep(2)
52
53 # 修改document文档树,把完整图片的display属性修改为block
54 js_code = '''
55 var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "block";
56 '''
57
58 # 执行js代码
59 driver.execute_script(js_code)
60
61 # 截取图片
62 image = cut_image(driver)
63
64 return image
65
66 # 获取有缺口图片
67 def get_image2(driver):
68 time.sleep(2)
69
70 # 修改document文档树,把完整图片的display属性修改为block
71 js_code = '''
72 var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "none";
73 '''
74
75 # 执行js代码
76 driver.execute_script(js_code)
77
78 # 截取图片
79 image = cut_image(driver)
80
81 return image
82
83 # 获取滑块滑动距离
84 def get_distance(image1, image2):
85 # 小滑块右侧位置
86 start = 60
87
88 # 像素差
89 num = 60
90 print(image1.size)
91 for x in range(start, image1.size[0]):
92 for y in range(image1.size[1]):
93
94 # 获取image1完整图片每一个坐标的像素点
95 rgb1 = image1.load()[x, y]
96
97 # 获取image2缺口图片每一个坐标的像素点
98 rgb2 = image2.load()[x, y]
99 # (60, 86, 40) (60, 86, 40) rgb
100 print(rgb1, rgb2)
101
102 # abs获取绝对值, 像素点比较的值
103 r = abs(rgb1[0] - rgb2[0])
104 g = abs(rgb1[1] - rgb2[1])
105 b = abs(rgb1[2] - rgb2[2])
106
107 # 如果条件成立,则找到缺口位置
108 if not (r < num and g < num and b < num):
109 # 有误差 - 7像素
110 return x - 7
111
112 # 模拟人的滑动轨迹
113 def get_strck_move(distance):
114 distance += 20
115
116 '''
117 滑动行为轨迹
118 加速公式:
119 v = v0 + a * t
120
121 路程公式:
122 s = v0 * t + 0.5 * a * (t ** 2)
123 '''
124
125 # 初速度
126 v0 = 0
127
128 # 时间
129 t = 0.2
130
131 # 位置
132 s = 0
133
134 # 滑动轨迹列表 向前滑动列表
135 move_list = []
136
137 # 中间值,作为加减速度的位置
138 mid = distance / 5 * 3
139
140 # 加减速度列表
141 v_list = [1, 2, 3, 4]
142
143 # 循环位移
144 while s < distance:
145 if s < mid:
146 # 随机获取一个加速度
147 a = v_list[random.randint(0, len(v_list) - 1)]
148
149 else:
150 # 随机获取一个减速度
151 a = -v_list[random.randint(0, len(v_list) - 1)]
152
153 '''
154 匀加速\减速运行
155 v = v0 + a * t
156
157 位移:
158 s = v * t + 0.5 * a * (t**2)
159 '''
160 # 获取初始速度
161 v = v0
162
163 # 路程公式:
164 s1 = v * t + 0.5 * a * (t ** 2)
165 s1 = round(s1) # 取整
166
167 # 加速公式:
168 # v = v0 + a * t
169 m_v = v + a * t
170
171 # 把当前加/减速度赋值给初始速度,以便下一次计算
172 v0 = m_v
173
174 # 把位移添加到滑动列表中
175 move_list.append(s1)
176
177 # 修改滑动初始距离
178 s += s1
179
180 # 后退列表, 自定义后退滑动轨迹,必须是负值
181 back_list = [-1, -1, -2, -3, -2, -1, -1, -2, -3, -2, -1, -1]
182
183 return {'move_list': move_list, 'back_list': back_list}
184
185 def main():
186 driver = webdriver.Chrome(r'D:\BaiduNetdiskDownload\chromedriver_win32\chromedriver.exe')
187 driver.implicitly_wait(10)
188 try:
189 driver.get('https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F')
190
191 # 1、输入用户名与密码,并点击登录
192 user_input = driver.find_element_by_id('LoginName')
193 user_input.send_keys('***')
194 time.sleep(0.2)
195
196 pwd_input = driver.find_element_by_id('Password')
197 pwd_input.send_keys('***')
198 time.sleep(2)
199
200 login_submit = driver.find_element_by_id('submitBtn')
201 login_submit.click()
202
203 # 2、获取完整的图片
204 image1 = get_image1(driver)
205
206 # 3、获取有缺口图片
207 image2 = get_image2(driver)
208
209 # 4、比对两张图片,获取滑动距离
210 distance = get_distance(image1, image2)
211 print(distance)
212
213 # 5、模拟人的滑动轨迹
214 move_dict = get_strck_move(distance)
215 # 获取前进滑动轨迹
216 move_list = move_dict['move_list']
217 # 获取后退滑动轨迹
218 back_list = move_dict['back_list']
219
220 # 6、开始滑动
221 move_tag = driver.find_element_by_class_name('geetest_slider_button')
222 # 点击摁住滑动按钮
223 ActionChains(driver).click_and_hold(move_tag).perform()
224
225 # 向前滑动
226 for move in move_list:
227 ActionChains(driver).move_by_offset(xoffset=move, yoffset=0).perform()
228 time.sleep(0.1)
229
230 time.sleep(0.1)
231
232 # 向后滑动
233 for back in back_list:
234 ActionChains(driver).move_by_offset(xoffset=back, yoffset=0).perform()
235 time.sleep(0.1)
236
237 # 制作微妙晃动
238 ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform()
239 ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform()
240
241 time.sleep(0.1)
242
243 # 释放滑动按钮
244 ActionChains(driver).release().perform()
245
246 time.sleep(100)
247
248 finally:
249 driver.close()
250
251 if __name__ == '__main__':
252 main()