一、了解滑动验证码的工作原理
滑动验证码是一种常见的人机验证方式,它要求用户在指定时间内完成拖动一个图片滑块的操作,以证明该用户是人而非机器程序。因此,想要打败滑动验证码,首先要了解它的工作原理。具体来说,滑动验证码的验证过程包括以下几个步骤:
1、在页面中生成一张含有特定标识的图片,并将其切分成若干个大小相同的滑块;
2、用户在指定时间内,通过鼠标或手指拖动一个图片滑块,将其对齐到页面中显示的指定位置上;
3、系统比对用户滑块的特定标识和页面中滑块的特定标识,如果匹配则视为该用户是可信的人类用户,否则认为该用户是机器程序。
二、破解滑动验证码的通用思路
虽然每个滑动验证码都会有一定的差异,但是我们可以总结出一些通用的破解思路,具体分为以下几点:
1、分析滑动验证图片标识的生成方式,例如是否基于时间戳、部分采用静态元素等;
2、分析滑块位置计算的算法,例如是否固定或者模糊化,在这个基础上针对验证码做合适的区块划分;
3、分析滑块特征提取及比对的算法,例如在目标区域内获取特征点、计算哈希等等,针对滑块位置模糊及噪声做合适的处理;
4、根据前三点的信息做合适的模拟,并通过模拟来破解滑动验证码。
三、破解滑动验证码的具体方法
接下来,我们分别从图片标识、滑块位置计算和滑块特征提取三个方面来具体介绍破解滑动验证码的方法。
1、破解图片标识
滑动验证码的图片标识通常是由一些字符、数字、线条等随机生成的图案拼接而成,包括静态和动态元素。破解滑动验证码需要先对图片进行处理,获取图片标识,并将其与后续的任务进行比对。在许多滑动验证码中,图片标识是通过JS生成的。通过使用Selenium这样的自动化测试工具可以获取到JS返回内容中标识的值。如果验证码的图片标识是由特定的时间戳生成的,可以先请求验证码的页面获取到相同时间戳的页面,并通过正则表达式从页面html中获取标识。
```python # 使用Selenium来获取验证码图片标识的值 from selenium import webdriver driver = webdriver.Chrome(executable_path='chromedriver.exe') driver.get(url) time.sleep(3) # 通过JS获取到图片标识的值 style = driver.find_element_by_id('captcha').get_attribute('style') pattern = re.compile(r"background-image: url\((.*?)\);.*background-position: (.*?) (.*?)px;", re.S) result = pattern.findall(style) # result[0][0] 为图片的url,result[0][1]为图片x坐标,result[0][2]为图片y坐标 ```2、破解滑块位置计算
滑块验证码的关键是如何计算滑块的位置。一些滑块位置计算算法通常是基于时间戳,也有一些算法会包含一些复杂的逻辑。我们可以通过了解滑块位置算法及其模糊化技巧来对其进行破解。
我们可以得到一个运动轨迹,然后根据运动轨迹进行分析。在大多数情况下,滑块位置计算算法中的时间戳会出现偏差,因此需要做一些微调来弥补。可以通过对抗式生成网络(GAN)训练等方法,结合不同的算法,进行计算。
```python # Python 代码示例 # 模拟获取下滑滑块的方法 def get_tracks(distance, seconds): # 一个轨迹由多个轨迹段组成,每个轨迹段滑动的时间也不同,通过融合轨迹段达到时间累加的效果 # v0 为起始速度,vd 为结束速度,a为加速度,t为时间,S为位移,v为速度。加速部分与减速部分对称 v0 = 0 vt = 0.5 a = 4 tracks = [] current = 0 mid = distance * 4 / 5 while current < distance: if current < mid: a = 4 else: a = -4 t = random.randint(10, 50) / 100 * (1 + random.random()) s = v0 * t + 0.5 * a * (t ** 2) vt = vt + a * t current += s tracks.append(round(vt * seconds)) return tracks ```3、破解滑块特征提取
滑动验证码通常在滑块上添加了若干条噪线或者在滑块周边加入干扰物,来增加其难度,但这些也是可以破解的。我们可以通过对滑块进行特征点提取,计算哈希值等算法来破解滑块的特征识别,可以使用OpenCV等工具库来提取特征点(SIFT,SURF,ORB等算法)。
```python # Python 代码示例 # 使用OpenCV提取特征点及哈希值 import cv2 import numpy as np # 提供滑块图片和正确位置参数 def process_image(img, pos): # 灰度化 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯模糊 blur = cv2.GaussianBlur(gray, (3, 3), 0) # 边缘提取 canny = cv2.Canny(blur, 100, 200) # 找轮廓 contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 在轮廓中查找正确的轮廓 min_x = pos[0] max_x = pos[0] + pos[2] min_y = pos[1] max_y = pos[1] + pos[3] for contour in contours: # 去除小轮廓 if cv2.contourArea(contour) < pos[-1] - 1: continue # 查找包含滑块的轮廓 startX, startY, w, h = cv2.boundingRect(contour) endX = startX + w endY = startY + h if startX < min_x or endX > max_x or startY < min_y or endY > max_y: continue # cv2.rectangle(canny, (startX, startY), (endX, endY), (0, 255, 0), 5) # 提取特征点 img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) sift = cv2.xfeatures2d.SIFT_create() kp, des = sift.detectAndCompute(img_gray[startY:endY, startX:endX], None) # 判断特征点是否符合条件 if len(kp) < 10: continue # 需要30个特征点才能做出决策 m = hashlib.md5() for point in np.float32([kp[i].pt for i in range(30)]): m.update(str(point).encode()) return m.hexdigest() ```总结
以上是一些简单的方法,可以欺骗大部分的滑动验证码。当然,也可以结合多种方法、多个工具、多个人工参数等技术手段,实现更好的自动破解效果。同时,也需要认识到,打败滑动验证码是一个动态的过程,验证码设计者也在不断升级相应的技术手段,因此,作为破解方,我们也需要不断更新我们的技术手段,才能保持相对竞争的优势。