python day07
1、破解极验滑动验证
2、BeautifulSoup解析库
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('_tank_') 194 time.sleep(0.2) 195 196 pwd_input = driver.find_element_by_id('Password') 197 pwd_input.send_keys('k46709394.') 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()