在项目中有时验证码是滑块拼图形式的,这种验证码该如何完成验证呢?
有以下几个步骤:
目录
第一步:得到验证码图片
第二步:匹配缺口照片在完整照片的位置
第三步:机器模拟人工滑动轨迹
第四步:判断拼图是否成功
第五步:滑块拼图递归循环调用
附录
一、得到验证码图片
1、思路
- 获取完整图片和缺口图片的base64数据
- 转换base64数据为图片
2、实践方法
封装
def get_images(self):
"""第一步:得到验证码图片base64数据"""
# 得到完整的图片base64数据,"return"必须加上
full_js = "return document.getElementsByTagName('img')[0].src"
full_image = self.executeScript(full_js, loc=None)
# 得到缺口的图片base64数据
gap_js = "return document.getElementsByTagName('img')[1].src"
gap_image = self.executeScript(gap_js, loc=None)
# 设置保存路径
base_path = fun().upPath() + "/data/image"
full_path = base_path + "/full_image.png"
gap_path = base_path + "/gap_image.png"
# 转换
self.base64_to_image(full_image, full_path)
self.base64_to_image(gap_image, gap_path)
# 返回路径
return full_path, gap_path
def base64_to_image(self,base64_str , image_path=None):
"""在第一步里:base64转化为image"""
base64_data = re.sub('^data:image/.+;base64,', '', base64_str)
byte_data = base64.b64decode(base64_data)
image_data = BytesIO(byte_data)
img = Image.open(image_data)
if image_path:
img.save(image_path)
return img
完整的图片:full_image.png
缺口的图片:gap_image.png
二、匹配缺口照片在完整照片的位置 返回目录
1、思路
- 读取完整图片和缺口图片信息
- 匹配缺口照片在完整照片的位置
2、实践方法
封装
def match_gaps(self, full, gap):
"""第二步:匹配缺口照片在完整照片的位置"""
# 读取图片文件信息
img_full = cv2.imread(full)
# 以灰度模式加载图片
template = cv2.imread(gap)
# 方法
methods = [cv2.TM_SQDIFF_NORMED, cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF_NORMED]
# 记录每个方法的距离
left = []
# 最接近值
min_ = []
for method in methods:
# 匹配
res = cv2.matchTemplate(img_full, template, method)
# 获取相关内容
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if method == cv2.TM_SQDIFF_NORMED:
min_.append(min_val - 0.0)
left.append(min_loc[0])
else:
min_.append(1.0 - max_val)
left.append(max_loc[0])
index = min_.index(numpy.min(min_))
print("选用第{:d}个方法, 差为:{:f},距离为:{:d}".format(index+1, min_[index], left[index]))
return left[index]
三、机器模拟人工滑动轨迹 返回目录
1、思路
- 滑块移动轨迹
- 机器模拟人工滑动轨迹
2、实践方法
封装
def sliding_track(self, distance):
"""第三步:机器模拟人工滑动轨迹"""
# 按住按钮
self.click_and_hold(loc.verifyButton_loc)
# 获取轨迹
track = self.get_track(distance)
print(f"获取轨迹:{track}")
print("++++++++++++++++++++++++++++++++++++++++++++")
for t in track:
self.move_by_offset(t)
self.move_by_offset(5)
self.move_by_offset(-5)
# 松开按钮
self.release()
def get_track(self, distance):
"""在第三步里:滑块移动轨迹"""
track = []
current = 0
# 阈值
mid = distance * 3 / 4
t = random.randint(5, 6) / 10
v = 0
while current < distance:
if current < mid:
a = 6
else:
a = -7
v0 = v
v = v0 + a * t
move = v0 * t + 3 / 4 * a * t * t
current += move
track.append(round(move))
return track
四、判断拼图是否存在 返回目录
1、思路
- 判断拼图是否存在
- 存在的话返回true
2、实践方法
封装
def judgeBox(self):
"""第四步:判断拼图是否存在"""
box_js = "return document.getElementsByClassName('verifybox')"
box_is = self.executeScript(box_js, loc=None)
return len(box_is) > 0
五、滑块拼图递归循环调用 返回目录
1、思路
- 判断拼图存在的话重新再执行以上方法
2、实践方法
封装
def loop(self):
"""第五步:滑块拼图递归循环调用"""
# 得到验证码图片
full_img_path, gap_img_path = self.get_images()
# 匹配缺口照片在完整照片的位置
number = self.match_gaps(full_img_path, gap_img_path)
print(f"缺口照片的位置为:{number}")
# 机器模拟人工滑动轨迹
self.sliding_track(number)
if self.judgeBox():
self.loop()
滑动结果:
虽然现在能达到模拟人工进行滑动模块,但是成功率不是很高!