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

操作环境

  • 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

文章推荐

浅谈 thinkphp composer 扩展包加载原理

.NET6项目连接数据库方式方法

分布式搜索引擎Elasticsearch基础入门学习

解析内存中的高性能图结构

使用Ref还是Reactive?

Ffmpeg分布式视频转码问题总结

探索FSM (有限状态机)应用

CSS3新增选择器(属性选择器、结构伪类选择器、伪元素选择器...

vue核心原理(Diff算法、虚拟dom)

git 撤销merge

K8S 性能优化 - OS sysctl 调优

Java ES 实现or查询