记一次 极验滑块验证分析并通过

操作环境

  • win10 、 mac
  • Python3.9
  • selenium、seleniumwire

分析

最近在做的一个项目登录时会触发一个滑块验证,就长下面这个样子请添加图片描述 可以很明显的看出来是极验3代验证,借助之前写阿里云盾的经验使用selenium+pyautoui先测试一下,详细可参考:阿里云盾滑块验证请添加图片描述 直接提示被怪物吃掉了!!! 还是先来研究一下官方文档看一下验证的业务逻辑:极验验证接入文档在这里插入图片描述 本以为是检测到了selenium,手动测试了一下发现是可以滑过的,那就是说明应该是滑动的轨迹触发了风控。请添加图片描述

分析了一波效验规则及原理,搞明白原理就好办了

解决方案

使用selenium请求url,并触发滑块验证

def open(self):
   """
    登录模块
    """
    # 定位密码登录
    self.driver.find_element_by_xpath('//*[@id="app"]/div/div/div/div/div/div[1]/div[2]').click()
    # 输入账号
    username = '123456'
    self.driver.find_element_by_xpath('//*[@id="app"]/div/div/div/div/div/div[2]/div[1]/form/div[1]/div/div/input').send_keys(username)
    time.sleep(1)
    # 输入密码
    password = '123456789'
    self.driver.find_element_by_xpath('//*[@id="app"]/div/div/div/div/div/div[2]/div[1]/form/div[2]/div/div/input').send_keys(password)
    time.sleep(1)
    # 登录
    self.driver.find_element_by_xpath('//*[@id="app"]/div/div/div/div/div/div[2]/div[3]/button').click()

获取验证图片并计算滑块距离

def get_images(self):
   """
   获取验证码图片
   :return: 图片的location信息
   """
   # 带缺口图片,使用js定位并读取图片的data信息 data:image/png;base64,直接调用识别缺口
   fullgb = self.driver.execute_script('return document.getElementsByClassName("geetest_canvas_bg geetest_absolute")[0].toDataURL("image/png")')
   # 完整图片,使用js定位并读取图片的data信息 data:image/png;base64,直接调用识别缺口
   bg = self.driver.execute_script('return document.getElementsByClassName("geetest_canvas_fullbg geetest_fade geetest_absolute")[0].toDataURL("image/png")')
   return bg, fullgb

def get_decode_image(self, location_list):
   """
   解码图片的base64数据
   """
   # 提取图片base64数据
   _, img = location_list.split(",")
   # 数据转换为Bytes字节
   img = base64.decodebytes(img.encode())
   # 读取图片
   new_im: PngImagePlugin.PngImageFile = image.open(BytesIO(img))
   # new_im.convert("RGB")
   # new_im.save(filename)
   return new_im

def compute_gap(self, img1, img2):
   """
   计算缺口偏移 这种方式成功率很高
   """
   # 将图片修改为RGB模式
   img1 = img1.convert("RGB")
   img2 = img2.convert("RGB")
   # 计算差值
   diff = ImageChops.difference(img1, img2)
   # 灰度图
   diff = diff.convert("L")
   # 二值化
   diff = diff.point(self.table, '1')
   left = 43
   for w in range(left, diff.size[0]):
       lis = []
       for h in range(diff.size[1]):
           if diff.load()[w, h] == 1:
               lis.append(w)
           if len(lis) > 5:
               return w

生成滑动轨迹

def get_tracks(self, distance, seconds, ease_func):
    """
    :param distance: 缺口位置
    :param seconds:  时间
    :param ease_func: 生成函数
    :return: 轨迹数组
    """
    tracks = [0]
    offsets = [0]
    for t in np.arange(0.0, seconds, 0.1):
        ease = ease_func
        offset = round(ease(t / seconds) * distance)
        tracks.append(offset - offsets[-1])
        offsets.append(offset)
    return tracks

滑动模块

def move_to_gap(self, track):
     """滑动滑块"""
     print('第一步,点击滑动按钮')
     slider = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_slider_button')))
     ActionChains(self.driver).click_and_hold(slider).perform()
     time.sleep(1)
     print('第二步,拖动元素')
     for track in track:
         ActionChains(self.driver).move_by_offset(xoffset=track, yoffset=0).perform()  # 鼠标移动到距离当前位置(x,y)
         time.sleep(0.0001)

效果

请添加图片描述

完美解决


资源下载

作者:|拉灯的小手|,原文链接: http://www.imooc.com/article/325351

文章推荐

Spring Authorization Server(AS)从 Mysql 中读取客户端、...

golang 方法接收者

评估指标与评分(上):二分类指标

数仓血缘关系数据的存储与读写

解决库存扣减及订单创建时防止并发死锁的问题

python 如何在多层循环中使用break/continue

就是 Spring 设计了一个lx.gongxuanwang.com

CentOS 8及以上版本配置IP的方法,你 get 了吗

EasyExcel · 写excel

JPA自动生成POJO

Centos 安装 docker

聊聊C#中的Visitor模式