bilibili的滑动验证码图片比较好玩,和前一篇不大一样。
采用canvas方法,分析发现只找到一个图片,不过,可以通过设置display截图方式获得2张图(完整图片,带缺口的图片),取得图片后接下来的方式和前一篇一样,偏移位置参数存在差异,需要自行调试。完整代码如下
#!/usr/bin/env python # encoding: utf-8 #@author: jack #@contact: 935650354@qq.com #@site: https://www.cnblogs.com/jackzz import re from time import sleep from selenium import webdriver import random import requests from PIL import Image from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from io import BytesIO from selenium.webdriver.common.action_chains import ActionChains USERNAME = '123456' PASSWORD = '123456' class BiliLogin(object): def __init__(self): ''' 初始化 ''' self.login_url = 'https://passport.bilibili.com/login' self.driver = webdriver.Firefox() self.wait = WebDriverWait(self.driver,10) self.driver.maximize_window() def input_info(self): ''' 输入账号密码 :return: ''' self.driver.get(self.login_url) username = self.wait.until(EC.presence_of_element_located((By.ID,'login-username'))) password = self.wait.until(EC.presence_of_element_located((By.ID,'login-passwd'))) username.send_keys(USERNAME) password.send_keys(PASSWORD) sleep(1) def click_login_button(self): ''' 点击登陆按钮 :return: ''' login_button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'btn-login'))) login_button.click() sleep(1) def get_captcha_image(self): ''' 获取验证码图片 :return: ''' geetest_canvas_bg = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'geetest_canvas_bg'))) geetest_canvas_bg.screenshot('bg.png') image_bg = Image.open('bg.png') #通过js代码修改标签样式 显示图片2 js = 'var change = document.getElementsByClassName("geetest_canvas_fullbg");change[0].style = "display:block;"' self.driver.execute_script(js) sleep(3) geetest_canvas_fullbg = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'geetest_canvas_fullbg'))) geetest_canvas_fullbg.screenshot('fullbg.png') image_fullbg = Image.open('fullbg.png') return image_bg,image_fullbg def get_diff_location(self,image1, image2): ''' 通过像素对比 找到缺口位置 :param image1: :param image2: :return: ''' for x in range(65, image1.size[0]): for y in range(image1.size[1]): if self.is_similar(image1, image2, x, y) == False: # 判断成立 表示xy这个点 两张图不一样 return x def is_similar(self,image1, image2, x, y): pixel1 = image1.getpixel((x, y)) pixel2 = image2.getpixel((x, y)) for i in range(0, 3): if abs(pixel1[i]) - pixel2[i] >= 60: return False return True def get_track(self,x): ''' 滑块移动轨迹 初速度 v =0 单位时间 t = 0.2 位移轨迹 tracks = [] 当前位移 ccurrent = 0 :param x: :return: ''' v = 0 t = 0.2 tracks = [] current = 0 mid = x*4/5#到达mid值开始减速 while current < x: if current < mid: a = random.randint(1,3) else: a = -random.randint(2,4) # a = 2 v0 = v # 单位时间内位移公式 s = v0 * t + 0.5 * a * (t ** 2) # 当前位移 current = current + s tracks.append(round(s)) v = v0 + a * t return tracks def move_to_xoffset(self,tracks): element = self.driver.find_element_by_class_name('geetest_slider_button') ActionChains(self.driver).click_and_hold(element).perform() for x in tracks: ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform() ActionChains(self.driver).release(element).perform() sleep(3) def main(self): self.input_info() self.click_login_button() image_bg,image_fullbg = self.get_captcha_image() xoffset = self.get_diff_location(image_bg,image_fullbg) print(xoffset) tracks = self.get_track(xoffset-7) print(tracks) self.move_to_xoffset(tracks) sleep(2) try: self.driver.find_elements_by_class_name('xxxxxxx') except: self.driver.refresh() self.main() if __name__ == '__main__': bili = BiliLogin() try: count = 5 while count > 0: bili.main() count -= 1 except Exception as e: print('识别错误,继续') finally: print('恭喜通过滑块验证') sleep(2) bili.driver.quit()
来源:博客园
作者:点点花飞谢
链接:https://www.cnblogs.com/jackzz/p/11444409.html