Day07
课堂笔记:
破解极验滑动验证
from selenium import webdriver from selenium.webdriver import ActionChains from PIL import Image import time import random # 截取图片函数 def cut_image(driver): driver.save_screenshot('image.png') img = driver.find_element_by_class_name('geetest_canvas_img') left = img.location['x'] upper = img.location['y'] right = left + img.size['width'] lower = upper + img.size['height'] image_obj = Image.open('image.png') img_cut = image_obj.crop((left, upper, right, lower)) # img_cut.show() return img_cut # 得到完整图片 def get_image1(driver): js_code = ''' var x = document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display="block"; console.log(x) ''' time.sleep(0.2) driver.execute_script(js_code) time.sleep(0.2) img1 = cut_image(driver) return img1 # 得到缺口图片 def get_image2(driver): js_code = ''' var x = document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display="none"; console.log(x) ''' time.sleep(0.2) driver.execute_script(js_code) time.sleep(0.2) img2 = cut_image(driver) return img2 # 对比图片,得到滑动距离 def get_distance(img1, img2): # 小滑块右侧位置 start_location = 60 # 像素差 threshold = 60 for i in range(start_location, img1.size[0]): for j in range(img1.size[1]): # 获得点(i,j)处的RGB像素值 rgb1 = img1.load()[i, j] rgb2 = img2.load()[i, j] r = abs(rgb1[0] - rgb2[0]) g = abs(rgb1[1] - rgb2[1]) b = abs(rgb1[2] - rgb2[2]) if not (r < threshold and g < threshold and b < threshold): # 有误差,减去7 return i-7 def get_tracks(distance): distance += 20 v0 = 0 a_list = [3, 4, 5] t = 0.2 s = 0 # 向前滑动轨迹 forward_tracks = [] mid = distance * 3 / 5 while s < distance: if s < mid: a = a_list[random.randint(0, 2)] else: a = -a_list[random.randint(0, 2)] v = v0 stack = v * t + 0.5 * a * (t ** 2) # 每次拿到的位移 stack = round(stack) s += stack v0 = v + a * t forward_tracks.append(stack) back_tracks = [-1, -1, -2, -3, -2, -3, -2, -2, -3, -1] return {'forward_tracks': forward_tracks, 'back_tracks': back_tracks} def main(user, pwd): driver = webdriver.Chrome() driver.maximize_window() try: driver.implicitly_wait(10) driver.get('https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F') username = driver.find_element_by_id('LoginName') username.send_keys(user) time.sleep(1) password = driver.find_element_by_id('Password') password.send_keys(pwd) time.sleep(1) submit = driver.find_element_by_id('submitBtn') submit.click() time.sleep(1) # 获取完整图片 img1 = get_image1(driver) # 获取缺口图片 img2 = get_image2(driver) # 获取移动距离 distance = get_distance(img1, img2) # 获取滑动轨迹,模拟人的滑动轨迹 tracks = get_tracks(distance) button = driver.find_element_by_class_name('geetest_slider_button') ActionChains(driver).click_and_hold(button).perform() for forward_track in tracks['forward_tracks']: ActionChains(driver).move_by_offset(xoffset=forward_track, yoffset=0).perform() time.sleep(0.2) for back_track in tracks['back_tracks']: ActionChains(driver).move_by_offset(xoffset=back_track, yoffset=0).perform() ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform() ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform() time.sleep(0.1) ActionChains(driver).release().perform() time.sleep(3) finally: driver.close() if __name__ == '__main__': user = '********' pwd = '****************' main(user, pwd)