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