破解bilibili滑块验证码

  其实我并没有成功,想要模拟人工滑动轨迹骗过验证太难了,我试了好多参数,每次都被拒绝了。我琢磨着是不是要考虑用微积分去设计运动轨迹。。。
  思路其实很简单,分别获取完整图片和不完整图片,比较图片的缺口,再将滑块滑到缺口处即可。若要说存在难度的地方,或许就是中间执行了一步js。
  如果有哪位大神成功模拟滑动轨迹,烦请赐教。。。
  不多说了,上代码。

import time
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC


class Bilibili(object):
    def __init__(self):
        self.url = 'https://passport.bilibili.com/login'
        self.browser = webdriver.Chrome()
        self.browser.maximize_window()
        self.wait = WebDriverWait(self.browser, 10)
        self.complete_img = ''
        self.incomplete_img = ''
        self.slider = ''
        self.position = []
        self.left = 120
        self.track = []
        self.main()

    def main(self):
        self.browser.get(self.url)
        self.send_key()
        self.get_incomplete_img()
        self.get_complete_img()
        self.get_gap()
        self.set_track()
        self.move_to_gap()
        self.browser.quit()

    def send_key(self):
        self.browser.get(self.url)
        login = WebDriverWait(self.browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".btn-login")))
        self.browser.find_element_by_id('login-username').send_keys('xxxx')
        self.browser.find_element_by_id('login-passwd').send_keys('xxxx')
        login.click()
        self.slider = WebDriverWait(self.browser, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '.geetest_slider_button')))

    def get_incomplete_img(self):
        self.browser.save_screenshot('screen.png')
        self.incomplete_img = self.browser.find_element_by_css_selector('.geetest_slicebg')
        size = self.incomplete_img.size
        location = self.incomplete_img.location
        top, bottom = 2 * location['y'], 2 * (location['y'] + size['height'])
        left, right = 2 * location['x'], 2 * (location['x'] + size['width'])
        self.position = [left, top, right, bottom]
        self.incomplete_img = Image.open(r'screen.png').crop((left, top, right, bottom))

    def get_complete_img(self):
        self.change_css_style()
        self.browser.save_screenshot('screen.png')
        left, top, right, bottom = self.position[0], self.position[1], self.position[2], self.position[3]
        self.complete_img = Image.open(r'screen.png').crop((left, top, right, bottom))

    def change_css_style(self):
        js = 'document.querySelectorAll("canvas")[3].style="display:block"'
        self.browser.execute_script(js)
        time.sleep(1)

    def get_gap(self):
        for ii in range(self.left, self.incomplete_img.size[0]):
            for jj in range(self.complete_img.size[1]):
                if not self.compare_img(ii, jj):
                    self.left = round(ii / 2 - 8)
                    return

    def compare_img(self, x, y, gap=60):
        pixel1 = self.incomplete_img.load()[x, y]
        pixel2 = self.complete_img.load()[x, y]
        if abs(pixel1[0] - pixel2[0]) < gap and abs(pixel1[1] - pixel2[1]) < gap and abs(pixel1[2] - pixel2[2]) < gap:
            return True
        else:
            return False

    def set_track(self):
        mid = 0.8 * self.left
        current = 0
        t = 0.2
        v = 0
        while current < self.left:
            if current < mid:
                a = 2
            else:
                a = -3
            v0 = v
            v = v0 + a * t
            move = v0 * t + 1 / 2 * a * t * t
            current += move
            self.track.append(round(move))

    def move_to_gap(self):
        ActionChains(self.browser).click_and_hold(self.slider).perform()
        for each_move in self.track:
            if each_move == 0:
                continue
            ActionChains(self.browser).move_by_offset(xoffset=each_move, yoffset=0).perform()
        time.sleep(0.5)
        ActionChains(self.browser).release().perform()


if __name__ == '__main__':
    spider = Bilibili()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值