selenium 处理滑块验证的重点

前言

在爬取数据中,不可避免的会遇到各种验证,上一篇文章说了二维码验证的办法

python识别二维码验证码的有效方法

示例

本篇文章讲的是遇到滑块验证的解决方案,本例是在一个b2b的网站内遇到的滑块验证

重点

真实人的拖动操作,是y轴和x都有变化的。这是重中之重。

思路

  1. 保存完整图片和缺口图片
  2. 找到缺口和图片的距离
  3. 生成移动轨迹
  4. 松开鼠标,确定移动结果

保存(完整和缺口)图片的代码:

def get_code_image(driver, fiel_name, ele_name='token-img', is_by_id=True):
    if is_by_id is True:
        code_element = driver.find_element_by_id(ele_name)
    else:
        code_element = driver.find_element_by_css_selector(ele_name)
    code_element.location_once_scrolled_into_view
    driver.save_screenshot(fiel_name)
    left = code_element.location_once_scrolled_into_view['x']
    top = code_element.location_once_scrolled_into_view['y']
    right = code_element.size['width'] + left
    height = code_element.size['height'] + top
    im = Image.open(fiel_name)
    img = im.crop((left, top, right, height))  # 截取指定元素图片保存
    save_res = img.save(fiel_name)
    return save_res

处理缺口和完整图片需要设置页面元素的展示和隐藏不同页面操作不同,本例使用的是执行js控制页面元素。

      js_code = """
                       var x = document.getElementsByClassName('gt_slice')[0].style.display="none";
                       console.log(x)
                   """
            # 执行js代码
            self.browser.execute_script(js_code)

找缺口距离的代码

def get_distance(cut_image, full_image):
    cut_image = Image.open(cut_image)  # 缺口背景图
    full_image = Image.open(full_image)  # 完整背景图
    threshold = 86  # 灰度值正好为86,86,86 这个是透明度的差值,边界值像素的RGB中的B值为准
    for i in range(55, cut_image.size[0]):  # 75为滑块的截图最右边阴影到图片最左端的长度
        for j in range(0, cut_image.size[1]):
            pixel1 = cut_image.getpixel((i, j))
            pixel2 = full_image.getpixel((i, j))
            res_R = abs(pixel1[0] - pixel2[0])  # 计算RGB差
            res_G = abs(pixel1[1] - pixel2[1])  # 计算RGB差
            res_B = abs(pixel1[2] - pixel2[2])  # 计算RGB差

            if res_R > threshold and res_G > threshold and res_B > threshold:
                print(i-7)
                return i-7
    return 0

根据距离计算出拖动的弧度

def get_stacks(distance):
    distance+5
    '''
        拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速
        变速运动基本公式:
        ① v=v0+at       匀加速\减速运行
        ② s=v0t+½at²    位移
        ③ v²-v0²=2as    
     '''
    # 初速度
    v0 = 0
    # 加减速度列表
    a_list = [50, 65, 80]
    # 时间
    t = 0.4
    # 初始位置
    s = 0
    # 向前滑动轨迹
    forward_stacks = []
    mid = distance * 3 / 5
    while s < distance:
        if s < mid:
            a = a_list[random.randint(0, 2)]
        else:
            a = -a_list[random.randint(0, 2)]
        v = v0
        stack = v * t + 0.5 * a * (t ** 2)
        # 每次拿到的位移
        stack = round(stack)
        if (s + stack) > distance:
            stack = distance - s + 5
        s += stack
        v0 = v + a * t
        forward_stacks.append(stack)
    back_stacks = [-5,]
    print(forward_stacks)
    return {'forward_stacks': forward_stacks, 'back_stacks': back_stacks}

重点

接下来是拖动要真实模拟人的操作,不可能y轴不变,这是重中之重。

        n= 0
        for forward_stack in forward_stacks:
            ActionChains(self.browser).move_by_offset(xoffset=forward_stack, yoffset=n).perform()
            n += 1 + random.randint(1, 2)
            time.sleep(0.5)
        for back_stack in back_stacks:
            ActionChains(self.browser).move_by_offset(xoffset=back_stack, yoffset=n).perform()
            time.sleep(0.01)
        time.sleep(0.5)

n += 1 + random.randint(1, 2)

yoffset=n

这两行是重点,很多文章中没有介绍。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值