zoukankan      html  css  js  c++  java
  • BILIBILI之滑块验证

    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()
    完整代码
  • 相关阅读:
    [Scala] akka actor编程(一)
    随便说说
    [Java] Java执行Shell命令
    [Scala] Scala基础知识
    [Linux] 账户管理命令(二)
    [Linux] 账户管理命令(一)
    [Kerberos] Java client访问kerberos-secured cluster
    沟通与影响技术培训
    Python
    ML 基础知识
  • 原文地址:https://www.cnblogs.com/jackzz/p/11444409.html
Copyright © 2011-2022 走看看