破解核心思路:
1、如何确定滑块滑动的距离?
滑块滑动的距离,需要检测验证码图片的缺口位置
滑动距离 = 终点坐标 - 起点坐标
然后问题转化为我们需要屏幕截图,根据selenium中的position方法并进行一些坐标计算,获取我们需要的位置
2、坐标我们如何获取?
起点坐标:
每次运行程序,位置固定不变,滑块左边界离验证码图片左边界有6px的距离
终点坐标:
每次运行程序,位置会变,我们需要计算每次缺口的位置
怎么计算终点也就是缺口的位置?
先举个例子,比如我下面两个图片都是120*60的图片,一个是纯色的图片,一个是有一个蓝色线条的图片(蓝色线条位置我事先设定的是60px位置),我现在让你通过程序确定蓝色线条的位置,你怎么确定?
答案:
遍历所有像素点色值,找出色值不一样的点的位置来确定蓝色线条的位置
这句话该怎么理解?大家点开我下面的图片,是不是发现图片都是由一个一个像素点组成的,120*60的图片,对应的像素就是横轴有120个像素点,纵轴有60个像素点,我们需要遍历两个图片的坐标并对比色值,从(0,0)(0,1)......一直到(120,60),开始对比两个图片的色值,遇到色值不一样的,我们return返回该位置即可
下面是简单代码演示,获取缺口位置为60,跟我预先设定的位置一样,后面会详细介绍该方法如何操作
而我们目标网站的验证码图片也是类似,这是我截图的,一个是没有缺口的验证码,一个是有缺口的验证码,我们同样需要遍历,但是注意一点的是,我们这次遍历不是从图片(0,0)开始遍历,而是需要从滑块的右侧边缘开始遍历
接下来开始上代码,用selenium模拟登陆,输入用户名和密码,这些我就不再截图代码了,想必大家应该都会的,本文会分享完整源码给大家,当然代码也存在一些缺陷,希望大家在测试过程中能改进指正,具体的很多问题,仍然需要大家自己去运行,去体会,才行发现问题
1、获取验证码位置坐标,尺寸大小
验证码需要截图,大概手写了一些计算过程,最后需要的验证码位置是上下左右的一个区域,我们从屏幕上根据这个区域进行截图
代码在运行中,发现计算的区域和实际截图有出入,我根据数据,多次测试运行,发现截图区域设定为(558,215,816,374)相对合适,可以截到验证码,这里是程序的问题之一,大家有兴趣可以测试,看该地方如何优化
这一步是返回缺口位置left
这个方法是比较色值差异
计算滑动距离=119 - 边缘空隙6 = 113
做到这一步,我们得出了需要滑动113px,然后我们的滑动,需要满足物理学规律,即先加速,后减速的过程,因为人的实际操作也是这样的,刚开始先加速,到后面开始减速
我设定的减速位置为mid,也就是滑动到五分之四的位置时候,速度开始降下来
中间定义了一个加速度a,当没有到4/5距离时候,加速度为1,当滑动最后1/5距离时,加速度变为-2,该代码参考崔大神的方法,根据数学公式,计算得出滑动轨迹,就相对模拟了一种相对真实的人的滑动过程
def get_track(self, distance):
"""
根据偏移量获取移动轨迹
:param distance: 偏移量
:return: 移动轨迹
"""
track = []
# 当前位移
current = 0
mid = distance * 4 / 5
# 计算间隔
t = 0.2
# 初速度
v = 0
while current < distance:
if current < mid:
# 加速度为正1
a = 1
else:
# 加速度为负2
a = -2
# 初速度v0
v0 = v
# 当前速度v = v0 + at
v = v0 + a * t
# 移动距离x = v0t + 1/2 * a * t^2
move = v0 * t + 1 / 2 * a * t * t
# 当前位移
current += move
# 加入轨迹
track.append(round(move))
return track
这是计算得出的滑动轨迹
另外注意,如果拖动过程发现拖得不够,就设置为-10或者-11,让轨迹多走点,如果发现拖得过了,就设置为-12,-13,让轨迹少走点,多尝试
总结:
本文主要分享破解思路,遇到bug解决方式,最后能调参数破解成功,读懂本文的意思是目的,需要大家动手去体会其中的一些关键思路