美文网首页
某站滑动验证码

某站滑动验证码

作者: 奇楠之后 | 来源:发表于2020-05-01 21:21 被阅读0次

    b站使用的滑动验证码为由极验提供服务,其登录过程:

    1. b站向自己服务器请求得到 gt,challenge 参数
    2. 携带 gt,challenge 参数请求极验服务器get.php,得到图片滑动的相关参数,包括缺口图,完整背景图,滑块图等数据(图片被打乱)
    3. 浏览器使用canvas渲染出正常的图片
    4. 用户拖动滑块至缺口,本地js会记录拖动过程中鼠标的移动轨迹,进行加密得到参数 w,携带参数 w 请求极验服务器ajax.php,验证码轨迹是否异常,验证通过会得到一个 validate 参数
    5. gt,challenge,validate,username,password 提交表单完成登录

    使用selenium登录

    1. 从canvas获取完整图片
         # canvas  有一个属性 toDataURL,获取到图片流数据 
        def save_img(self, img_name, class_name):
            # img_name 图片保存名称
            # class_name 图片在HTML中ClassName
            getImgJS = 'return document.getElementsByClassName("' + class_name + '")[0].toDataURL("image/png");'
            img = self.driver.execute_script(getImgJS)
            base64_data_img = img[img.find(',') + 1:]
            image_base = base64.b64decode(base64_data_img)
            file = open(img_name, 'wb')
            file.write(image_base)
            file.close()
    
    1. 比较图片得到滑动距离
        # 判断颜色是否相近
        def is_similar_color(self, x_pixel, y_pixel):
            for i, pixel in enumerate(x_pixel):
                if abs(y_pixel[i] - pixel) > 50:
                    return False
            return True
    
        # 计算距离
        def get_offset_distance(self, cut_image, full_image):
            # 两个参数为图片流数据
            for x in range(cut_image.width):
                for y in range(cut_image.height):
                    cpx = cut_image.getpixel((x, y))
                    fpx = full_image.getpixel((x, y))
                    if not self.is_similar_color(cpx, fpx):
                        img = cut_image.crop((x, y, x + 50, y + 40))
                        # 保存一下计算出来位置图片,看看是不是缺口部分
                        img.save("1.png")
                        return x
    
    1. 模拟用户滑动
        # 开始移动
        def start_move(self, distance):
            # 定位滑块
            element = self.driver.find_element_by_xpath('//div[@class="geetest_slider_button"]')
    
            # 这里就是根据移动进行调试,计算出来的位置不是百分百正确的,加上一点偏移
            distance -= element.size.get('width') / 2
            distance += 25
    
            # 按下鼠标左键 move_by_offset 从当前坐标移动到 (x,y)
            ActionChains(self.driver).click_and_hold(element).perform()
            time.sleep(0.2)
            while distance > 0:
                if distance > 10:
                    # 如果距离大于10,就移动快一点
                    span = random.randint(5, 8)
                else:
                    # 快到缺口了,就移动慢一点
                    span = random.randint(2, 3)
                # 每次移动的速度不一样,看起来卡顿,比较慢
                randy = random.randint(-3,3)
                ActionChains(self.driver).move_by_offset(span, randy).perform()
                distance -= span
                # time.sleep(random.randint(10, 30) / 100)
    
            ActionChains(self.driver).move_by_offset(distance, 1).perform()
            # 释放鼠标
            ActionChains(self.driver).release(on_element=element).perform()
    

    表单提交登录

    参考文章:
    极验js分析

    相关文章

      网友评论

          本文标题:某站滑动验证码

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