Python实现滑块验证码详解
简介
滑块验证码是当前主流的验证码之一,其通过让用户拖动滑块来验证身份,比传统的输入验证码更加便捷和直观。因此在很多网站中都广泛应用。
实现流程
1. 获取验证码图片
首先,需要从验证码接口或者其他途径获取验证码图片。一般来说,验证码图片都是由字符或者数字组成的图片,而滑块通常是一张带有缺口的验证码图片。
2. 切分验证码图片
将获取到的验证码图片进行切分,分为包含滑块的图片部分和滑块部分两组图片。
其中,包含滑块的图片部分且不包含滑块缺口的一侧为背景图片部分,另外一侧分别为滑块位置的原图和滑块的验证图。
3. 模板匹配
使用模板匹配算法,通过比对滑块验证图和包含滑块的原图的相似度,以此来得出滑块在原图中的位置。
通过一些基本的计算,可以得到滑块移动的距离,即为滑块实际距离 - 滑块原本位置的距离。
示例1:通过OpenCV实现
import cv2
import numpy as np
BG_PATH = 'screenshot_bg.png'
SLIDER_PATH = 'screenshot_slider.png'
class Verifier:
def __init__(self):
self.bg = cv2.imread(BG_PATH)
self.slider = cv2.imread(SLIDER_PATH)
self.width, self.height = self.bg.shape[:2]
self.temp = 'temp.jpg'
def find_slider(self):
result = cv2.matchTemplate(self.bg, self.slider, cv2.TM_CCOEFF_NORMED)
return np.where(result >= 0.98)
def cut_image(self, img, x, y, w, h):
return img[y:y + h, x:x + w]
def detect_slider_position(self):
x, y = self.find_slider()
x, y = int(x[0]), int(y[0])
# 滑块位置
slider = self.cut_image(self.bg, x, y, 75, 45)
cv2.imwrite(self.temp, slider)
# 滑块验证图
slider_img = cv2.imread(self.temp)
# 包含滑块的原图
bg = self.cut_image(self.bg, 0, 0, x + 75, self.height)
res = cv2.matchTemplate(bg, slider_img, cv2.TM_CCOEFF_NORMED)
x, *_ = np.where(res > 0.9)
distance = x[0]
print('距离为:', distance)
v = Verifier()
v.detect_slider_position()
在这个示例中,我们使用了OpenCV库对验证码进行切分,返回滑块在原图中的位置,并计算出滑块的移动距离。
示例2:通过Selenium和Pillow实现
from io import BytesIO
from selenium import webdriver
from PIL import Image
DRIVER_PATH = 'chromedriver.exe'
URL = 'https://www.geetest.com/demo/slide-popup.html'
class Verifier:
def __init__(self):
self.driver = webdriver.Chrome(DRIVER_PATH)
def get_screenshot(self):
# 获取滑块页面的截图
screenshot = self.driver.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
return screenshot
def get_position(self):
# 获取滑块图片,并得到滑块在原图中的位置
screenshot = self.get_screenshot()
captcha_img = screenshot.crop((690, 390, 1030, 510))
background_img = screenshot.crop((0, 0, 690, 510))
captcha_img.save('captcha.jpg')
background_img.save('background.jpg')
captcha = Image.open('captcha.jpg')
bg = Image.open('background.jpg')
res = Image.fromarray(np.array(bg) - np.array(captcha))
res.save('res.jpg')
w, h = captcha.size
for distance in range(w):
for i in range(h):
r, g, b = captcha.getpixel((distance, i))
if r < 60 and g < 60 and b < 60:
print('距离为:', distance)
return distance
def move_slider(self, distance):
# 拖动滑块
slider = self.driver.find_element_by_css_selector('.geetest_slider_button')
webdriver.ActionChains(self.driver).click_and_hold(on_element=slider).perform()
webdriver.ActionChains(self.driver).move_by_offset(xoffset=distance - 7, yoffset=0).perform()
webdriver.ActionChains(self.driver).release(on_element=slider).perform()
v = Verifier()
v.driver.get(URL)
v.get_position()
v.move_slider(210)
在这个示例中,我们使用了Selenium库模拟用户滑动验证码操作,并使用了Pillow库对验证码进行切分。
总结
本文从实现流程出发,给出了两个示例代码,演示了如何通过代码实现滑块验证码。在实现过程中,我们利用了图像处理技术,使用模板匹配算法得出了滑块在原图中的位置,并根据计算得到了滑块的移动距离。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现滑块验证码详解 - Python技术站