破解b站极验验证码

 

 

这就是极验验证码,经过拖动滑块移动拼图来验证。咱们观察到点击滑块时拼图才会出现,因此咱们能够在点击滑块以前截取图像,点击滑块再截取一次图像,将先后两次图像作比较就能够找到图片改动的位置。得到位置后,咱们须要模拟人类的操做将滑块移动到指定的位置。代码以下:web

#识别b站极验验证码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from io import BytesIO import io from PIL import Image import time from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver import ActionChains EMAIL = "wdl1078390625@qq.com" PASSWORD = "wdl-075483267123"

class BilibiliTest(): def __init__(self): self.url = "https://passport.bilibili.com/login" self.browser = webdriver.Chrome() self.wait = WebDriverWait(self.browser,20) self.email = EMAIL self.password = PASSWORD self.browser.get(self.url) email = 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'))) email.send_keys(self.email) password.send_keys(self.password) self.button = self.get_test_button() self.img1,self.img2 = self.get_test_image() #保存图片
        self.img1.save('b1.png') self.img2.save('b2.png') def get_test_button(self): button = self.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.gt_slider_knob'))) return button #得到截图中图片的位置
    def get_position(self): action = ActionChains(self.browser) action.move_to_element(self.button) self.button.click() img = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'.gt_cut_fullbg.gt_show'))) location = img.location size = img.size top = location['y'] bottom = location['y'] + size['height'] left = location['x'] right = location['x'] + size['width'] return (top,bottom,left,right) #得到图片 
    def get_test_image(self): top,bottom,left,right = self.get_position() time.sleep(1) screenshot = self.get_screenshot() #浏览器缩放,因此要乘1.25,读者根据本身的需求修改之
        img1 = screenshot.crop((left*1.25,top*1.25,right*1.25,bottom*1.25)) time.sleep(1) ActionChains(self.browser).click_and_hold(self.button).perform() time.sleep(1) screenshot = self.get_screenshot() img2 = screenshot.crop((left*1.25,top*1.25,right*1.25,bottom*1.25)) return (img1,img2) #对比像素点是否一致
    def is_pixel_equal(self,img1,img2,x,y): pixel1 = img1.load()[x,y] pixel2 = img2.load()[x,y] #副本图片中常有干扰的灰块,与原图像素不一致但差距小,用threshold变量排除干扰
        threshold = 80
        if abs(pixel1[0]-pixel2[0]) < threshold and \ abs(pixel1[1]-pixel2[1]) < threshold and \ abs(pixel1[2]-pixel2[2]) < threshold: return True else: return False #对比各像素点是否一致 
    def get_gap(self,img1,img2): left = 80
        for i in range(left,img1.size[0]): for j in range(img1.size[1]-30): if not self.is_pixel_equal(img1,img2,i,j): left = i return left return left #获取滑块移动轨迹
    def get_track(self, distance): # 移动轨迹
        track = [] current = 0 mid = (distance-30) * 5 / 9 mid2 = (distance-30) * 7 / 9 t = 0.2
        # 初速度
        v = 3
        #初始加速度为2
        a = 2
        #初始加速度增量
        aa = 0.3
          
        while current < distance-25: if current < mid: a += aa
            elif current < mid2: a += aaelse: if a < 0 : a -= aa
                else: a = -a + 1
            # 初速度v0
            v0 = v # 当前速度v = v0 + at
            v = v0 + a * t # 移动距离x = v0t + 1/2 * a * t^2
            move = v0 * t + 1 / 2 * a * t * t # 当前位移
            current += round(move) # 加入轨迹
 track.append(round(move)) track.append(0) track.append(-3) track.append(-2) print("distance:"+str(distance)+"track:") print(track) return track #移动滑块
    def move_to_gap(self,button,tracks): ActionChains(self.browser).click_and_hold(button).perform() for x in tracks: ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform() time.sleep(0.3) ActionChains(self.browser).release().perform() #截屏
    def get_screenshot(self): screenshot = self.browser.get_screenshot_as_png() screenshot = Image.open(BytesIO(screenshot)) return screenshot def login(self): distance = self.get_gap(self.img1,self.img2) track = self.get_track(distance) self.move_to_gap(self.button,track) time.sleep(10) def main(args): bilibili = BilibiliTest() bilibili.login() return 0 if __name__ == '__main__': import sys sys.exit(main(sys.argv))
相关文章
相关标签/搜索