当前位置:网站首页>Crack sliding verification code

Crack sliding verification code

2022-04-23 17:58:00 Feng Ye 520

import logging
import time
import random
import re
import requests
from urllib import parse
import pdb
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from PIL import Image
from io import BytesIO
import numpy as np


class Bilibili(object):
    """docstring for Bilibili"""
    js="""
        console.log(document.cookie);
        var keys=document.cookie.match(/[^ =;]+(?=\=)/g);
        console.log(keys);
        if (keys) {
        for (var i = keys.length; i--;)
        document.cookie=keys[i]+'=0;expires=' + new Date( 0).toUTCString();
        console.log(document.cookie);
        } """
    def __init__(self):
        """ Constructors """
        super(Bilibili,self).__init__()
        self.browser=webdriver.Chrome()
        self.browser.set_page_load_timeout(20)
        self.browser.implicitly_wait(10)

    def __del__(self):
        """ Destructor """
        if self.browser is not None:
            self.browser.quit()

    def logging(self,username,password):

        self.browser.get("https://passport.bilibili.com/login")
        dom_input_id = self.browser.find_element_by_id("login-username")
        dom_input_keyword = self.browser.find_element_by_id("login-passwd")
        dom_btn_log = self.browser.find_element_by_xpath('//*[@class="btn-box"]/a[1]')
        #pdb.set_trace()
        dom_input_id.send_keys(username)
        dom_input_keyword.send_keys(password)

        flag_success = False
        while not flag_success:
            image_full_bg = self.get_image("gt_cut_fullbg_slice")
            # Download the complete verification diagram
            image_bg = self.get_image("gt_cut_bg_slice")
            # Download the verification diagram with gap
            diff_x = self.get_diff_x(image_full_bg, image_bg)
            #pdb.set_trace()
            track = self.get_track(diff_x)
            result = self.simulate_drag(track)
            print(result)

            if u' Verification passed ' in result:
                flag_success = True
            elif u' There is an error :' in result:
                self.browser.execute_script('location.reload()')
                continue
            elif u' Again ' in result:
                time.sleep(4)
                continue
            elif u' eat ' in result:
                time.sleep(5)
            else:
                break

        if flag_success:
            time.sleep(random.uniform(1.5, 2))
            self.browser.execute_script(self.js)


    def get_image(self,class_name):
        """
        Download and restore the verification diagram of polar test
        Args:
            class_name: Verify the location of the diagram html Labeled class name
        Returns:
            Return to verification diagram
        Errors:
            IndexError: list index out of range. ajax Timeout not loaded complete , Lead to image_slices It's empty
        """
        image_slices = self.browser.find_elements_by_class_name(class_name)
        #pdb.set_trace()
        if len(image_slices) == 0:
            print('No such a class')
        div_style=image_slices[0].get_attribute('style')
        print(div_style)
        #pdb.set_trace()
        image_url = re.findall("background-image: url\(\"(.*)\"\); background-position: (.*)px (.*)px;",div_style)[0][0]
#        image_url = re.findall("background-image: url\("(.*)"\); background-position: (.*)px (.*)px;",div_style)[0][0]
        image_url = image_url.replace("webp","jpg")
        image_filename = parse.urlsplit(image_url).path.split('/')[-1]

        location_list = list()
        for image_slice in image_slices:
            location = dict()
            location['x'] = int(re.findall("background-image: url\(\"(.*)\"\); background-position: (.*)px (.*)px;",
                                            image_slice.get_attribute('style'))[0][1])

            location['y'] = int(re.findall("background-image: url\(\"(.*)\"\); background-position: (.*)px (.*)px;",
                                           image_slice.get_attribute('style'))[0][2])

            location_list.append(location)

        headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"}
        response = requests.get(image_url,headers=headers)

        image = Image.open(BytesIO(response.content))
        image = self.recover_image(image,location_list)
        return image

    def recover_image(self,image,location_list):
        """
        Restore validation image
        Args:
            image: Scrambled verification images (PIL.Image data type )
            location_list: Verify the position of each fragment of the image
        Returns:
            Restored image
        """
        new_im = Image.new('RGB',(260,116))
        im_list_upper = []
        im_list_down = []
        for location in location_list:
            if location['y'] == -58:
                im_list_upper.append(image.crop((abs(location['x']), 58, abs(location['x']) + 10, 116)))
            if location['y'] == 0:
                im_list_down.append(image.crop((abs(location['x']), 0, abs(location['x']) + 10, 58)))

        x_offset = 0
        for im in im_list_upper:
            new_im.paste(im, (x_offset, 0))
            x_offset += im.size[0]

        x_offset = 0
        for im in im_list_down:
            new_im.paste(im, (x_offset, 58))
            x_offset += im.size[0]

        return new_im

    def get_diff_x(self,image1,image2):
        """
        Calculate the notch position of the verification diagram (x Axis )
        The size of the two original images is the same 260*116, Then go through two for Loop to compare the of each pixel in turn RGB value ,
        If RGB One of the three elements differs by more than 50 Then it is considered that the position of the gap has been found
        Args:
            image1: Images 1
            image2: Images 2
        Returns:
            x_offset
        """
        for x in range(0, 260):
            for y in range(0, 116):
                if not self.__is_similar(image1, image2, x, y):
                    print(1111111111111111111,x)
                    return x


    def __is_similar(self, image1, image2, x_offset, y_offset):
        """
        Judge image1, image2 Of [x, y] Whether this pixel is similar , If the pixel RGB The values differ by 50 within , Think similar .
        Args:
            image1: Images 1
            image2: Images 2
            x_offset: x coordinate
            y_offset: y coordinate
        Returns:
           boolean
        """
        pixel1 = image1.getpixel((x_offset, y_offset))
        pixel2 = image2.getpixel((x_offset, y_offset))
        for i in range(0, 3):
            if abs(pixel1[i] - pixel2[i]) >= 50:
                return False
        return True

    def get_track(self, x_offset):

        track = list()
        length = x_offset - 6
        x = random.randint(1,5)
        while length - x >4:
            track.append([x,0,0.1])
            length=length - x
            x= random.randint(1,15)

        for i in range(length):
            if x_offset>47:
                track.append([1,0,random.randint(10,12)/100.0])
            else:
                track.append([1, 0, random.randint(13, 14)/100.0])
        print(22222222,track)
        print((np.array(track)[:,0]).sum())
        return track

    def simulate_drag(self, track):
                                                       
        dom_div_slider = self.browser.find_element_by_xpath('//*[@id="gc-box"]/div/div[3]/div[2]')

        ActionChains(self.browser).click_and_hold(on_element=dom_div_slider).perform()

#        for x,y,z in track:
#            ActionChains(self.browser).move_to_element_with_offset(
#                to_element=dom_div_slider,
#                xoffset=x+22,
#                yoffset=y+22).perform()
#            time.sleep(z)
        
        for x,y,z in track:
            ActionChains(self.browser).move_by_offset(
                xoffset=x,
                yoffset=y).perform()
            time.sleep(z)
            
#        ActionChains(self.browser).move_by_offset(    
#                xoffset=(np.array(track)[:,0]).sum(),
#                yoffset=0).perform()

        time.sleep(0.9)
        ActionChains(self.browser).release(on_element=dom_div_slider).perform()
        time.sleep(1)
        dom_div_gt_info = self.browser.find_element_by_class_name('gt_info_type')
        return dom_div_gt_info.text


if __name__ == '__main__':
    bilibili=Bilibili()
    bilibili.logging('username','password')
    
    
    
    
    
    
    
    
    

版权声明
本文为[Feng Ye 520]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230546134290.html