今日内容: 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) rgb100 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 - 7111 112 # 模拟人的滑动轨迹113 def get_strck_move(distance):114 distance += 20115 116 '''117 滑动行为轨迹118 加速公式:119 v = v0 + a * t120 121 路程公式:122 s = v0 * t + 0.5 * a * (t ** 2)123 '''124 125 # 初速度126 v0 = 0127 128 # 时间129 t = 0.2130 131 # 位置132 s = 0133 134 # 滑动轨迹列表 向前滑动列表135 move_list = []136 137 # 中间值,作为加减速度的位置138 mid = distance / 5 * 3139 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 * t156 157 位移:158 s = v * t + 0.5 * a * (t**2)159 '''160 # 获取初始速度161 v = v0162 163 # 路程公式:164 s1 = v * t + 0.5 * a * (t ** 2)165 s1 = round(s1) # 取整166 167 # 加速公式:168 # v = v0 + a * t169 m_v = v + a * t170 171 # 把当前加/减速度赋值给初始速度,以便下一次计算172 v0 = m_v173 174 # 把位移添加到滑动列表中175 move_list.append(s1)176 177 # 修改滑动初始距离178 s += s1179 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()
1 def get_strck_move(distance): 2 distance += 20 3 4 ''' 5 滑动行为轨迹 6 加速公式: 7 v = v0 + a * t 8 9 路程公式:10 s = v0 * t + 0.5 * a * (t ** 2)11 '''12 13 # 初速度14 v0 = 015 16 # 时间17 t = 0.218 19 # 位置20 s = 021 22 # 滑动轨迹列表 向前滑动列表23 move_list = []24 25 # 中间值,作为加减速度的位置26 mid = distance / 5 * 327 28 # 加减速度列表29 v_list = [1, 2, 3, 4]30 31 # 循环位移32 while s < distance:33 if s < mid:34 # 随机获取一个加速度35 a = v_list[random.randint(0, len(v_list) - 1)]36 37 else:38 # 随机获取一个减速度39 a = -v_list[random.randint(0, len(v_list) - 1)]40 41 '''42 匀加速\减速运行43 v = v0 + a * t44 45 位移:46 s = v * t + 0.5 * a * (t**2)47 '''48 # 获取初始速度49 v = v050 51 # 路程公式:52 s1 = v * t + 0.5 * a * (t ** 2)53 s1 = round(s1) # 取整54 55 # 加速公式:56 # v = v0 + a * t57 m_v = v + a * t58 59 # 把当前加/减速度赋值给初始速度,以便下一次计算60 v0 = m_v61 62 # 把位移添加到滑动列表中63 move_list.append(s1)64 65 # 修改滑动初始距离66 s += s167 68 # 后退列表, 自定义后退滑动轨迹,必须是负值69 back_list = [-1, -1, -2, -3, -2, -1, -1, -2, -3, -2, -1, -1]70 71 return { 'move_list': move_list, 'back_list': back_list}