美文网首页
爬虫总结之--滑动验证码

爬虫总结之--滑动验证码

作者: strive鱼 | 来源:发表于2018-07-02 23:15 被阅读0次

岁月蹉跎,转眼又浪费了一个月,准备重新的生活起来,知识点总结起来,之前的算法暂时停歇到年底,因为目前爬虫还没完全参透,接下来会在爬虫、spss、机器学习、建模、深度学习等方面进行系统全新的学习,总结的代码和一些感悟会写进简书里,大佬们多多指教。

今天学习了爬虫中验证码的识别--滑动验证码该类验证码的关键就在于原图(没有缺口的图)与有缺口的图的像素比较/从而得到缺口的位置/然后拖动滑块进行识别

知识点则主要涉及selenium 的用法
代码注释内容是对崔庆才--催大佬的书籍中源码的自我消化

滑动验证码的类型如下


image.png

下面为代码和注释部分

EMAIL = 'xxxxxxxx'
PASSWORD = 'xxxxxxx'
INIT_LEFT = 60
BORDER=6
class crackgeetest(object):
    def __init__(self):
        self.url='https://account.geetest.com/login'
        self.browser=webdriver.Chrome()
        self.wait=WebDriverWait(self.browser,20)
        self.email=EMAIL
        self.password=PASSWORD
        
    def __del__(self):
        self.browser.close()#关掉浏览器
    
    def get_slider(self):
        """
        获取滑动按钮
        """
        slider=self.wait.until(By.CLASS_NAME,'geetest_radar_tip')#根据class 名称来定位
        return slider
    
    def get_geetest_button(self):
        """
        获取初始验证按钮(这样才会显示出验证图片)
        :return:
        """
        button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip')))
        return button
    
    def get_position(self):
        """
        获取验证码的位置,并且返回验证码位置的元组
        """
        img=self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'geetest_canvas_img')))
        time.sleep(2)#等待两秒
        location=img.location
        size=img.size
        top,bottom,left,right=location['y'],location['y']+size['height'],location['x'],location['x']+size['width']#获取完整图片的位置
        return (top,bottom,left,right)
    
    def get_screenshot(self):#目的是获取完整图片的截图
        """
        获取验证码的截图,并且返回截图
        """
        screenshot=self.browser.get_screenshot_as_png()
        screenshot=Image.open(BytesIO(screenshot))
        return screenshot 
    
    def get_slider(self):
        """
        获取带缺口的图片,要使得该图片出现
        需要点击下方的滑块即可,动作一旦触发,图片中的缺口就会出现
        """
        slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))
        return slider 
    
    def get_geetest_image(self,name='captcha.png'):
        """
        获取带有缺口的验证码的图片截图
        """
        top,bottom,left,right=self.get_position()
        print ('验证码位置',top,bottom,left,right)
        screenshot=self.get_screenshot()#调用获取截图
        captcha=screenshot.crop((left,top,right,bottom))#注意为左上角和右下角
        captcha.save(name)
        return captcha
    
    def open(self):
        """
        打开网页并且输入用户名和密码
        """
        self.browser.get(self.url)
        email=self.wait.until(EC.presence_of_element_located((By.ID, 'email')))#获取键入框
        password=self.wait.until(EC.presence_of_element_located((By.ID, 'password')))#获取键入框
        email.send_keys(self.email)
        password.send_keys(self.password)
        
        
    """
    上边已经获取了两张图片的截图,这里来遍历每一个坐标点的像素RGB数据,如果两者的像素差在
    一定的范围内则说明像素相同,反之不同
    """  
    def is_pixel_equal(self,image1,image2,x,y):#比较像素
        """
        image1:不带缺口的图片
        image2:带有缺口的图片
        """
        pixel1=image1.load()[x,y]#本质上得到RGB数据(3个数)组成的数组
        pixel2=image2.load()[x,y]
        threshold=60#阈值的设定
        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,image1,image2):#获取缺口位置的方法
        left=60#缺口一般在滑块的右侧,如果要寻找缺口直接从滑块的右侧寻找即可,故遍历的起始坐标为60
        for i in range(left,image1.size[0]):
            for j in range(image1.size[1]):
                if not self.is_pixel_equal(image1,image2,i,j):#说明像素不同
                    left=i
                    return left 
        return left 
    
    def get_track(self,distance):#有了以上准备下面就开始拖动滑块
        """
        如果为匀速拖动,那么由于极验运用的是机器模型,必然会识别出是程序所为,验证不会通过
        所以崔大佬书中讲要先匀加速后匀减速
        x=v0*t+1/2*a*t*t
        v=v0+a*t
        """
        track=[]#运动轨迹
        current=0#当前位移
        mid=distance*4/5#减速阈值
        t=0.2#时间间隔
        v=0#初速度
        while current<distance:
            if current<mid:
                a=2#加速度为正
            else:
                a=-3
            vo=v
            v=vo+a*t
            move=vo*t+1/2*a*t*t
            current+=move
            track.append(round(move))#round 函数返回四舍五入
        return track #存入的为每个时间间隔内移动的距离
    def move_to_gap(self,slider,tracks):
        """
        第一个参数为get_slider()函数定位的滑块
        第二个参数为上面的函数得到的单位时间间隔滑块所在位置的集合
        """
        ActionChains(self.browser).click_and_hold(slider).perform()#先按住滑块
        for x in tracks:
            ActionChains(self.browser).move_by_offset(xoffset=x,yoffset=0).perform()#逐步移动到缺口处
        time.sleep(0.5)#然后停顿
        ActionChains(self.browser).release().perform()#释放滑块
        
    def login(self):#当上面模拟滑动验证成功时候,需要点击登陆按钮
        submit = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'login-btn')))
        submit.click()
        time.sleep(10)
        print('登录成功')
    def crack(self):
        self.open()#首先登陆到该极验界面
        button=self.get_geetest_button()
        button.click()#这样就会首先显示出完整的图片
        image1=self.get_geetest_image('captcha1.png')
        slider=self.get_slider()
        slider.click()#点按就会得到带有缺口的图片
        image2=self.get_geetest_image('captcha2.png')#得到带有缺口的图片位置
        gap=self.get_gap(image1,image2)
        print ('缺口位置',gap)
        gap-=BORDER#减去缺口位移
        track=self.get_track(gap)
        print ('滑动轨迹',track)
        self.move_to_gap(slider,track)
        success=self.wait.until(EC.text_to_be_present_in_element((By.CLASS_NAME, 'geetest_success_radar_tip_content'), '验证成功'))
        print (success)
        if not success:
            self.crack()
        else:
            self.login()
            
            
if __name__=='__main__':
    crack=crackgeetest()
    crack.crack()

后续还会自己总结书中代码进行学习

相关文章

  • 爬虫总结之--滑动验证码

    岁月蹉跎,转眼又浪费了一个月,准备重新的生活起来,知识点总结起来,之前的算法暂时停歇到年底,因为目前爬虫还没完全参...

  • 三. 突破反爬虫

    1.反爬虫措施一般分为四类:①基于验证码的反爬虫:传统验证码、逻辑验证码、滑动验证码、google访问时弹出的验证...

  • python爬虫之模拟移动

    爬虫的一大难点就是破解验证码。验证码大致上分为文字识别、滑动、文字点击、图像识别等,本文讲的是其中的滑动验证码。滑...

  • python爬虫之滑动验证码[完整版]

    爬虫的一大难点就是破解验证码。验证码大致上分为文字识别、滑动、文字点击、图像识别等,本文讲的是其中的滑动验证码。滑...

  • python爬虫之图像对比

    爬虫的一大难点就是破解验证码。验证码大致上分为文字识别、滑动、文字点击、图像识别等,本文讲的是其中的滑动验证码。滑...

  • python爬虫之轨迹算法

    爬虫的一大难点就是破解验证码。验证码大致上分为文字识别、滑动、文字点击、图像识别等,本文讲的是其中的滑动验证码。滑...

  • Python爬虫教程:验证码识别

    常见反爬虫手段:验证码1.简单图片,扭曲数字验证码2.中文顺序点击3.动态验证码4.滑动验证:滑动小方块到缺口5....

  • 破解滑动验证码

    最近爬虫采集数据遇到了验证码的障碍,需要破解某网站的滑动验证码(GEETEST)。 主要参考https://seg...

  • 验证码的识别

    验证码是一种反爬虫的措施,目前的验证码主要有图像验证码、极验滑动验证码、点触验证码、微博宫格验证码等。根据不同类型...

  • 了解爬虫1

    crapy爬虫=数据采集 简单:静态网站 难:动态、加密(逆向)、验证码(滑动、点击、倒立) 数据为王: 数据怎么...

网友评论

      本文标题:爬虫总结之--滑动验证码

      本文链接:https://www.haomeiwen.com/subject/eepruftx.html