有效解决图片滑块验证码(极验)--最新解决方案

一、图片滑块验证问题

这里我以头条的登录界面举例子,其他的类似这种都是大同小异。修改关键代码就可以了
入口连接:https://ad.oceanengine.com/pages/login/index.html

在这里插入图片描述

二、解决思路

    1.分析页面拿到背景图
    2.计算滑块所需要的距离,即缺口位置
    3.计算滑动轨迹
    4.进行滑动
分析页面取出背景图

核心代码:

# 获取全背景图,进行裁剪保存
img = browser.find_element_by_xpath('//*[@id="validate-big"]')
location = img.location
print("location: ", location)
size = img.size
print("验证码大小:", size)
left, up, right, down = location["x"], location["y"], location["x"] + size["width"], location["y"] + size[
    "height"]
print("截取后的图片信息:", left, up, right, down)
# 保存大背景图
browser.save_screenshot("toutiao.png")
# 截取小验证图
need_bg_img = Image.open("toutiao.png")
img_writer = need_bg_img.crop((left, up, right, down))  # 指定上下左右截取
img_writer.save("captcha.png")

通过selenium中xpath方法找到背景图,并且通过方法location和size确定图片的位置和大小,这已不是为了找到背景图位置,通过使用Pillow包将背景图截取出来,用来做之后的灰度化处理

计算滑块所需要的距离

先展示一下目标结果:
在这里插入图片描述

在这里插入图片描述

说明:左边的滑块y轴距离是不确定的,但是x轴是确定的,所以可以直接拿到x距离。然后右边是不固定的,可以通过对图像进行降噪或者边缘处理,由于技术问题,我直接进行变为灰度值,发现也还可以弄,获取到所有灰度值为255的,根据出现的y坐标频率最高的以及数值最大的判断得出缺口的x坐标,即缺口距离y轴距离。

核心代码:

# 转成灰度图进行处理
img = cv2.imread("captcha.png", 0)  # 由于Canny只能处理灰度图,所以将读取的图像转成灰度图
img = cv2.GaussianBlur(img, (3, 3), 0)  # 用高斯平滑处理原图像降噪。若效果不好可调节高斯核大小
canny = cv2.Canny(img, 200, 600)  # 调用Canny函数,指定最大和最小阈值,其中apertureSize默认为3。
# cv2.imshow('Canny', canny)
# cv2.waitKey(1)

# 获取图片大小
x_len, y_len = canny.shape

# 遍历每个像素获取到 X 值,进行统计
x_arr = []
for i in range(1, x_len):
    for j in range(1, y_len):
        if canny[i, j] == 255.:
            x_arr.append(j)
print("顺序打印看一下:", x_arr)

# 根据频率统计得到缺口距离y轴距离
former_dict = Counter(x_arr).most_common(5)
far_distance = max(dict(former_dict).keys())
distance = far_distance - 52
print(distance)
计算滑块轨迹

说明:为了不让头条识别出我们是机器滑动,所以我们可以采用之前学过的加速度原理,改变他的偏移量,让他速度忽快忽慢,和人的操作类似。

def get_track(distance):  # 人为滑动是先慢 中快 后慢
    """
    根据偏移量获取移动轨迹
    :param distance: 偏移量
    :return: 移动轨迹列表
    """
    track = []
    current = 0  # 当前位移
    mid = distance * 4 / 5  # 设定一个阈值进行改变加速度
    t = 1  # 计算间隔
    v = 0  # 初速度
    while current < distance:
        if current < mid:
            a = 1  # 加速度为正1
        else:
            a = -2  # 加速度为负2
        v0 = v  # 初速度v0
        v = v0 + a * t  # 当前速度v = v0 + at
        # 移动距离x = v0t + 1/2 * a * t^2
        move = v0 * t + 1 / 2 * a * t * t
        current += move  # 当前位移
        track.append(round(move))  # 加入轨迹
    track.append(distance-sum(track))
    return track

学过的物理加速度公式此刻是不是觉得有了用武之地!我上面设置的是先慢、中快、后慢。这个小伙伴们可以自己设置,只要不要一下子让机器‘顺利’的划过去就好。

最后就是滑动

说明:最后一步比较简单直接上代码

dis_list = get_track(distance)
print(dis_list[1:])
print(sum(dis_list))
button = browser.find_element_by_xpath('//*[@id="validate-drag-wrapper"]/div[2]/img')
ActionChains(browser).click_and_hold(button).perform()

for dis in dis_list:
        ActionChains(browser).move_by_offset(xoffset=dis, yoffset=0).perform()
ActionChains(browser).release().perform()
time.sleep(0.3)

总结:其实看了思路之后很简单,无非就是进入页面通过xpath找到滑块的位置,然后进行截图保存,之后通过高斯平滑进行降噪,将图片进行灰度化。这样是为了很好的找到缺口位置。网上也有比较RGB 的解决方案,个人觉得这个滑块没有必要。最后一步就是充分利用所学的物理知识进行模拟人的操作轨迹,自定义开始和结尾的速度。

会使用到的包:selenium+cv2+PIL就可以搞定

如果觉得有帮助到大家的可以帮忙点个关注,点个赞!想要源码的(已经测试成功的)可以加博主的微信私聊!

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值