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