Python Learning Day7

破解极验滑动验证

  博客园登录url:
    https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F

  代码逻辑:
    1、输入用户名与密码,并点击登录
    2、弹出滑动验证,获取有缺口与完整的图片
    3、通过像素点进行比对,获取滑动位移距离
    4、模拟人的行为轨迹
    5、开始滑动

  1 from selenium import webdriver  # 用来驱动浏览器的
  2 from selenium.webdriver import ActionChains  # 破解滑动验证码的时候用的 可以拖动图片
  3 import time
  4 from PIL import Image  # pip3 install pillow
  5 import random
  6 
  7 # 截图图片函数
  8 def cut_image(driver):
  9     # 获取整个页面图片,图片名字为'snap.png'
 10     driver.save_screenshot('snap.png')
 11 
 12     # 获取滑动小画图
 13     image = driver.find_element_by_class_name('geetest_canvas_img')
 14     print(image.location)
 15     print(image.size)
 16 
 17     # 获取小图片的左上右下的位置
 18     left = image.location['x']
 19     top = image.location['y']
 20     right = left + image.size['width']
 21     buttom = top + image.size['height']
 22     print(left, top, right, buttom)
 23 
 24     # 调用open方法打开全屏图片并赋值给image_obj对象
 25     image_obj = Image.open('snap.png')
 26 
 27     # 通过image_obj对象对小图片进行截取
 28     # box: The crop rectangle, as a (left, upper, right, lower)-tuple.
 29     img = image_obj.crop((left, top, right, buttom))
 30     # 打开截取后的小图片
 31     # img.show()
 32     return img
 33 
 34 # 获取完整图片
 35 def get_image1(driver):
 36     time.sleep(2)
 37 
 38     # 修改document文档树,把完整图片的display属性修改为block
 39     js_code = '''
 40         var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "block";
 41     '''
 42 
 43     # 执行js代码
 44     driver.execute_script(js_code)
 45 
 46     # 截取图片
 47     image = cut_image(driver)
 48 
 49     return image
 50 
 51 # 获取有缺口图片
 52 def get_image2(driver):
 53     time.sleep(2)
 54 
 55     # 修改document文档树,把完整图片的display属性修改为block
 56     js_code = '''
 57         var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "none";
 58     '''
 59 
 60     # 执行js代码
 61     driver.execute_script(js_code)
 62 
 63     # 截取图片
 64     image = cut_image(driver)
 65 
 66     return image
 67 
 68 # 获取滑块滑动距离
 69 def get_distance(image1, image2):
 70     # 小滑块右侧位置
 71     start = 60
 72 
 73     # 像素差
 74     num = 60
 75     print(image1.size)
 76     for x in range(start, image1.size[0]):
 77         for y in range(image1.size[1]):
 78 
 79             # 获取image1完整图片每一个坐标的像素点
 80             rgb1 = image1.load()[x, y]
 81 
 82             # 获取image2缺口图片每一个坐标的像素点
 83             rgb2 = image2.load()[x, y]
 84             # (60, 86, 40) (60, 86, 40) rgb
 85             print(rgb1, rgb2)
 86 
 87             # abs获取绝对值, 像素点比较的值
 88             r = abs(rgb1[0] - rgb2[0])
 89             g = abs(rgb1[1] - rgb2[1])
 90             b = abs(rgb1[2] - rgb2[2])
 91 
 92             # 如果条件成立,则找到缺口位置
 93             if not (r < num and g < num and b < num):
 94                 # 有误差 - 7像素
 95                 return x - 7
 96 
 97 # 模拟人的滑动轨迹
 98 def get_strck_move(distance):
 99     distance += 20
100 
101     '''
102     滑动行为轨迹
103     加速公式:
104         v = v0 + a * t
105         
106     路程公式:
107         s = v0 * t + 0.5 * a * (t ** 2)
108     '''
109 
110     # 初速度
111     v0 = 0
112 
113     # 时间
114     t = 0.2
115 
116     # 位置
117     s = 0
118 
119     # 滑动轨迹列表 向前滑动列表
120     move_list = []
121 
122     # 中间值,作为加减速度的位置
123     mid = distance / 5 * 3
124 
125     # 加减速度列表
126     v_list = [1, 2, 3, 4]
127 
128     # 循环位移
129     while s < distance:
130         if s < mid:
131             # 随机获取一个加速度
132             a = v_list[random.randint(0, len(v_list) - 1)]
133 
134         else:
135             # 随机获取一个减速度
136             a = -v_list[random.randint(0, len(v_list) - 1)]
137 
138         '''
139         匀加速\减速运行
140         v = v0 + a * t
141 
142         位移:
143         s = v * t + 0.5 * a * (t**2)
144         '''
145         # 获取初始速度
146         v = v0
147 
148         # 路程公式:
149         s1 = v * t + 0.5 * a * (t ** 2)
150         s1 = round(s1)  # 取整
151 
152         # 加速公式:
153         # v = v0 + a * t
154         m_v = v + a * t
155 
156         # 把当前加/减速度赋值给初始速度,以便下一次计算
157         v0 = m_v
158 
159         # 把位移添加到滑动列表中
160         move_list.append(s1)
161 
162         # 修改滑动初始距离
163         s += s1
164 
165     # 后退列表, 自定义后退滑动轨迹,必须是负值
166     back_list = [-1, -1, -2, -3, -2, -1, -1, -2, -3, -2, -1, -1]
167 
168     return {'move_list': move_list, 'back_list': back_list}
169 
170 def main():
171     driver = webdriver.Chrome(r'D:\BaiduNetdiskDownload\chromedriver_win32\chromedriver.exe')
172     driver.implicitly_wait(10)
173     try:
174         driver.get('https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F')
175 
176         # 1、输入用户名与密码,并点击登录
177         user_input = driver.find_element_by_id('LoginName')
178         user_input.send_keys('_tank_')
179         time.sleep(0.2)
180 
181         pwd_input = driver.find_element_by_id('Password')
182         pwd_input.send_keys('k46709394.')
183         time.sleep(2)
184 
185         login_submit = driver.find_element_by_id('submitBtn')
186         login_submit.click()
187 
188         # 2、获取完整的图片
189         image1 = get_image1(driver)
190 
191         # 3、获取有缺口图片
192         image2 = get_image2(driver)
193 
194         # 4、比对两张图片,获取滑动距离
195         distance = get_distance(image1, image2)
196         print(distance)
197 
198         # 5、模拟人的滑动轨迹
199         move_dict = get_strck_move(distance)
200         # 获取前进滑动轨迹
201         move_list = move_dict['move_list']
202         # 获取后退滑动轨迹
203         back_list = move_dict['back_list']
204 
205         # 6、开始滑动
206         move_tag = driver.find_element_by_class_name('geetest_slider_button')
207         # 点击摁住滑动按钮
208         ActionChains(driver).click_and_hold(move_tag).perform()
209 
210         # 向前滑动
211         for move in move_list:
212             ActionChains(driver).move_by_offset(xoffset=move, yoffset=0).perform()
213             time.sleep(0.1)
214 
215         time.sleep(0.1)
216 
217         # 向后滑动
218         for back in back_list:
219             ActionChains(driver).move_by_offset(xoffset=back, yoffset=0).perform()
220             time.sleep(0.1)
221 
222         # 制作微妙晃动
223         ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform()
224         ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform()
225 
226         time.sleep(0.1)
227 
228         # 释放滑动按钮
229         ActionChains(driver).release().perform()
230 
231         time.sleep(100)
232 
233     finally:
234         driver.close()
235 
236 if __name__ == '__main__':
237     main()from selenium import webdriver  # 用来驱动浏览器的
238 from selenium.webdriver import ActionChains  # 破解滑动验证码的时候用的 可以拖动图片
239 import time
240 from PIL import Image  # pip3 install pillow
241 import random
242 
243 # 截图图片函数
244 def cut_image(driver):
245     # 获取整个页面图片,图片名字为'snap.png'
246     driver.save_screenshot('snap.png')
247 
248     # 获取滑动小画图
249     image = driver.find_element_by_class_name('geetest_canvas_img')
250     print(image.location)
251     print(image.size)
252 
253     # 获取小图片的左上右下的位置
254     left = image.location['x']
255     top = image.location['y']
256     right = left + image.size['width']
257     buttom = top + image.size['height']
258     print(left, top, right, buttom)
259 
260     # 调用open方法打开全屏图片并赋值给image_obj对象
261     image_obj = Image.open('snap.png')
262 
263     # 通过image_obj对象对小图片进行截取
264     # box: The crop rectangle, as a (left, upper, right, lower)-tuple.
265     img = image_obj.crop((left, top, right, buttom))
266     # 打开截取后的小图片
267     # img.show()
268     return img
269 
270 # 获取完整图片
271 def get_image1(driver):
272     time.sleep(2)
273 
274     # 修改document文档树,把完整图片的display属性修改为block
275     js_code = '''
276         var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "block";
277     '''
278 
279     # 执行js代码
280     driver.execute_script(js_code)
281 
282     # 截取图片
283     image = cut_image(driver)
284 
285     return image
286 
287 # 获取有缺口图片
288 def get_image2(driver):
289     time.sleep(2)
290 
291     # 修改document文档树,把完整图片的display属性修改为block
292     js_code = '''
293         var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "none";
294     '''
295 
296     # 执行js代码
297     driver.execute_script(js_code)
298 
299     # 截取图片
300     image = cut_image(driver)
301 
302     return image
303 
304 # 获取滑块滑动距离
305 def get_distance(image1, image2):
306     # 小滑块右侧位置
307     start = 60
308 
309     # 像素差
310     num = 60
311     print(image1.size)
312     for x in range(start, image1.size[0]):
313         for y in range(image1.size[1]):
314 
315             # 获取image1完整图片每一个坐标的像素点
316             rgb1 = image1.load()[x, y]
317 
318             # 获取image2缺口图片每一个坐标的像素点
319             rgb2 = image2.load()[x, y]
320             # (60, 86, 40) (60, 86, 40) rgb
321             print(rgb1, rgb2)
322 
323             # abs获取绝对值, 像素点比较的值
324             r = abs(rgb1[0] - rgb2[0])
325             g = abs(rgb1[1] - rgb2[1])
326             b = abs(rgb1[2] - rgb2[2])
327 
328             # 如果条件成立,则找到缺口位置
329             if not (r < num and g < num and b < num):
330                 # 有误差 - 7像素
331                 return x - 7
332 
333 # 模拟人的滑动轨迹
334 def get_strck_move(distance):
335     distance += 20
336 
337     '''
338     滑动行为轨迹
339     加速公式:
340         v = v0 + a * t
341         
342     路程公式:
343         s = v0 * t + 0.5 * a * (t ** 2)
344     '''
345 
346     # 初速度
347     v0 = 0
348 
349     # 时间
350     t = 0.2
351 
352     # 位置
353     s = 0
354 
355     # 滑动轨迹列表 向前滑动列表
356     move_list = []
357 
358     # 中间值,作为加减速度的位置
359     mid = distance / 5 * 3
360 
361     # 加减速度列表
362     v_list = [1, 2, 3, 4]
363 
364     # 循环位移
365     while s < distance:
366         if s < mid:
367             # 随机获取一个加速度
368             a = v_list[random.randint(0, len(v_list) - 1)]
369 
370         else:
371             # 随机获取一个减速度
372             a = -v_list[random.randint(0, len(v_list) - 1)]
373 
374         '''
375         匀加速\减速运行
376         v = v0 + a * t
377 
378         位移:
379         s = v * t + 0.5 * a * (t**2)
380         '''
381         # 获取初始速度
382         v = v0
383 
384         # 路程公式:
385         s1 = v * t + 0.5 * a * (t ** 2)
386         s1 = round(s1)  # 取整
387 
388         # 加速公式:
389         # v = v0 + a * t
390         m_v = v + a * t
391 
392         # 把当前加/减速度赋值给初始速度,以便下一次计算
393         v0 = m_v
394 
395         # 把位移添加到滑动列表中
396         move_list.append(s1)
397 
398         # 修改滑动初始距离
399         s += s1
400 
401     # 后退列表, 自定义后退滑动轨迹,必须是负值
402     back_list = [-1, -1, -2, -3, -2, -1, -1, -2, -3, -2, -1, -1]
403 
404     return {'move_list': move_list, 'back_list': back_list}
405 
406 def main():
407     driver = webdriver.Chrome(r'D:\BaiduNetdiskDownload\chromedriver_win32\chromedriver.exe')
408     driver.implicitly_wait(10)
409     try:
410         driver.get('https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F')
411 
412         # 1、输入用户名与密码,并点击登录
413         user_input = driver.find_element_by_id('LoginName')
414         user_input.send_keys('_tank_')
415         time.sleep(0.2)
416 
417         pwd_input = driver.find_element_by_id('Password')
418         pwd_input.send_keys('k46709394.')
419         time.sleep(2)
420 
421         login_submit = driver.find_element_by_id('submitBtn')
422         login_submit.click()
423 
424         # 2、获取完整的图片
425         image1 = get_image1(driver)
426 
427         # 3、获取有缺口图片
428         image2 = get_image2(driver)
429 
430         # 4、比对两张图片,获取滑动距离
431         distance = get_distance(image1, image2)
432         print(distance)
433 
434         # 5、模拟人的滑动轨迹
435         move_dict = get_strck_move(distance)
436         # 获取前进滑动轨迹
437         move_list = move_dict['move_list']
438         # 获取后退滑动轨迹
439         back_list = move_dict['back_list']
440 
441         # 6、开始滑动
442         move_tag = driver.find_element_by_class_name('geetest_slider_button')
443         # 点击摁住滑动按钮
444         ActionChains(driver).click_and_hold(move_tag).perform()
445 
446         # 向前滑动
447         for move in move_list:
448             ActionChains(driver).move_by_offset(xoffset=move, yoffset=0).perform()
449             time.sleep(0.1)
450 
451         time.sleep(0.1)
452 
453         # 向后滑动
454         for back in back_list:
455             ActionChains(driver).move_by_offset(xoffset=back, yoffset=0).perform()
456             time.sleep(0.1)
457 
458         # 制作微妙晃动
459         ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform()
460         ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform()
461 
462         time.sleep(0.1)
463 
464         # 释放滑动按钮
465         ActionChains(driver).release().perform()
466 
467         time.sleep(100)
468 
469     finally:
470         driver.close()
471 
472 if __name__ == '__main__':
473     main()

 

posted @ 2019-06-19 14:43  走投无路只能来敲敲代码  阅读(281)  评论(0编辑  收藏  举报