滑块验证码作为一种常见的人机验证方式,旨在防止机器人或恶意程序的自动化攻击。然而,随着计算机视觉和深度学习技术的不断发展,破解滑块验证码的技术也日益成熟。本文将详细说明破解滑块验证码的重要点、难处,并介绍一种基于yolov8训练的模型的破解过程,并展示其效果。
一、破解滑块验证码的重要点:
1.1 图像分割:滑块验证码通常由背景图和滑块图组成,破解的第一步是提取各种滑块图像,本人收集了5种
1.2 滑块位置定位:确定滑块在背景图中的位置,以便后续的滑动模拟
1.3 滑块轨迹模拟:通过模拟用户的滑动轨迹,使得破解过程更加真实可信
2.1 多样性:滑块验证码的设计者会采用不同的背景图、滑块图以及滑块形状、大小等参数,增加了破解的难度。
2.2 干扰项:为了防止破解,滑块验证码通常会添加一些干扰项,如噪点、干扰线等,使得图像更加复杂,增加了破解的难度。
2.3 实时性:滑块验证码通常要求用户在一定时间内完成验证,破解过程需要在规定时间内完成,增加了破解的难度。
三、破解过程:
为了破解滑块验证码,我们采用了yolov8来训练模型,具体步骤如下:
3.1 数据预处理:艰苦的收集了14000张各色的图片的数据集。数据集进行预处理,包括图像增强、滑块图像分割、滑块位置标注等。
3.2 模型训练:使用yolov8模型对预处理后的数据集进行训练,以学习滑块图像的特征。
yolo detect train data=data.yaml model=best.pt epochs=1000 patience=100 batch=660 device=0 imgsz=320
训练效果99%点多,奈斯!
3.3 滑块位置定位:使用训练好的模型对滑块验证码进行图像分割和滑块位置定位,得到滑块的位置信息。
def get_element_slide_distance(self, slider_ele, background_ele, correct=0):
"""
根据传入滑块,和背景的节点,计算滑块的距离
该方法只能计算 滑块和背景图都是一张完整图片的场景,
如果是通过多张小图拼接起来的背景图,该方法不适用,后续会补充一个专门针对处理该场景的方法
:param slider_ele: 滑块图片的节点
:type slider_ele: WebElement
:param background_ele: 背景图的节点
:type background_ele:WebElement
:param correct:滑块缺口截图的修正值,默认为0,调试截图是否正确的情况下才会用
:type: int
:return: 背景图缺口位置的X轴坐标位置(缺口图片左边界位置)
"""
background_url = background_ele.get_attribute("src")
background = "./images/verifycode.jpg"
self.onload_save_img(background_url, background)
# 获取父元素的坐标
parent_location = background_ele.location
# 获取子元素的坐标
child_location = slider_ele.location
# 计算子元素在父元素中的相对坐标
relative_x = child_location['x'] - parent_location['x']
relative_y = child_location['y'] - parent_location['y']
result = self.yolo_det(background)
# if result is None or len(result) == 0:
# result = self.paddle_det.predict(background_01, threshold=0.8)
# result = result['boxes']
# 再使用tensor.numpy()进行转化
result = result[0].boxes.data.cpu().numpy()
distance = int(result[0][0])
print("当前滑块的信息:{},{}".format(result, distance))
os.remove(background)
return distance
3.4 滑块轨迹模拟:根据滑块的位置信息,模拟用户的滑动轨迹,以完成滑块验证码的破解。
def slide_verification(self, driver, slide_element, distance):
"""
:param driver: driver对象
:type driver:webdriver.Chrome
:param slide_element: 滑块的元组
:type slider_ele: WebElement
:param distance: 滑动的距离
:type: int
:return:
"""
start_url = driver.title
print("需要滑动的距离为:", distance)
locus = self.get_slide_locus(distance)
print("生成的滑动轨迹为:{},轨迹的距离之和为{}".format(locus, distance))
ActionChains(driver).click_and_hold(slide_element).perform()
time.sleep(0.5)
for loc in locus:
time.sleep(0.01)
ActionChains(driver).move_by_offset(loc, random.randint(-5, 5)).perform()
ActionChains(driver).context_click(slide_element)
ActionChains(driver).release(on_element=slide_element).perform()
time.sleep(2)
end_url = driver.title
print(start_url + "====" + end_url)
# if start_url == end_url:
# return -1
# print("第{}次验证失败,开启重试".format(6 - self.count))
# self.count -= 1
# self.slide_verification(driver, slide_element, distance)
return 0
四、效果展示
12月12日