Python实现图片滑动式验证识别方法
简介
图片滑动式验证(Slider Captcha)是一种常用的验证码形式,需拖动滑块将其拼接至滑块所在背景图片上,验证通过后才可以进行下一步操作。本文将介绍如何使用 Python 实现图片滑动式验证的识别方法。
目录
需求分析
为了实现图片滑动式验证的识别方法,我们需要完成以下几个任务:
1. 识别验证码中的背景图片和滑块图片
2. 计算滑块在背景图片中的位置
3. 模拟人手拖动滑块的过程
编程实现
本文中将使用 Python 中的 Pillow 库来完成图片操作,使用 Selenium 库模拟用户操作浏览器。完整的代码如下:
from PIL import Image, ImageChops
from selenium import webdriver
import time
class SliderCaptcha:
def __init__(self, url):
# 打开浏览器
self.driver = webdriver.Chrome()
self.driver.maximize_window()
# 访问网址
self.driver.get(url)
# 等待页面完全加载完成
time.sleep(5)
def get_images(self):
# 获取背景图片和滑块图片的链接
bg = self.driver.find_element_by_class_name('gt_cut_bg_slice')
block = self.driver.find_element_by_class_name('gt_cut_fullbg_slice')
bg_url = bg.get_attribute('style').split('url("')[1].split('");')[0]
block_url = block.get_attribute('style').split('url("')[1].split('");')[0]
# 下载图片并保存
self.driver.execute_script("document.getElementsByClassName('gt_cut_bg_slice')[0].style.display='block';")
bg_location_list = self.driver.find_element_by_class_name('gt_cut_bg_slice').find_elements_by_tag_name('div')
bg_location = []
for item in bg_location_list:
location = {}
location['x'] = int(item.location['x'])
location['y'] = int(item.location['y'])
bg_location.append(location)
bg_image = self.process_image(bg_url, bg_location)
self.driver.execute_script("document.getElementsByClassName('gt_cut_fullbg_slice')[0].style.display='block';")
block_location_list = self.driver.find_element_by_class_name('gt_cut_fullbg_slice').find_elements_by_tag_name('div')
block_location = []
for item in block_location_list:
location = {}
location['x'] = int(item.location['x'])
location['y'] = int(item.location['y'])
block_location.append(location)
block_image = self.process_image(block_url, block_location)
return bg_image, block_image
def process_image(self, url, location_list):
# 下载图片并剪切
image = Image.open(self.download_image(url))
image_list = []
for location in location_list:
image_list.append(image.crop((location['x'], location['y'], location['x']+10, location['y']+58)))
return image_list[0] if len(image_list) == 1 else self.merge_image(image_list, location_list)
def merge_image(self, image_list, location_list):
# 拼接图片
for index, location in enumerate(location_list):
if index == 0:
new_image = image_list[0]
else:
new_image = self.merge_two_image(new_image, image_list[index], location['x'], location_list[0]['x'])
return new_image
def merge_two_image(self, image1, image2, x_offset1, x_offset2):
# 拼接两张图片
diff = x_offset2 - x_offset1
image = ImageChops.offset(image2, (diff, 0))
new_image = Image.new(image1.mode, (image1.width+image2.width-diff, image1.height))
new_image.paste(image1, (0, 0))
new_image.paste(image, (image1.width-diff, 0))
return new_image
def download_image(self, url):
# 下载图片
response = self.driver.execute_script('''
var url = arguments[0];
var callback = arguments[1];
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function() {
if (xhr.status === 200) {
callback(xhr.response);
}
};
xhr.send();
''', url, lambda res: res)
return response
def get_gap(self, image1, image2):
# 获取滑块位置
diff = ImageChops.difference(image1, image2)
diff = diff.convert('L') # 转换为灰度图像
box = diff.getbbox() # 获取有效像素区域
return box[0]
def drag_slider(self, gap):
# 模拟人手拖动滑块
slider = self.driver.find_element_by_class_name('gt_slider_knob')
action = webdriver.ActionChains(self.driver)
action.click_and_hold(slider).perform()
for i in range(-5, gap, 5):
action.move_by_offset(5, 0).perform()
time.sleep(0.01)
action.move_by_offset(gap - i, 0).perform()
action.release(slider).perform()
def verify_success(self):
# 判断是否验证成功
result = self.driver.find_element_by_class_name('gt_info_text').text.strip()
if '验证成功' in result:
return True
else:
return False
def crack(self):
# 自动识别和拖拽滑块
bg_image, block_image = self.get_images()
gap = self.get_gap(bg_image, block_image)
self.drag_slider(gap)
time.sleep(1)
if self.verify_success():
print('验证成功')
else:
# 失败时重新验证
print('验证失败,重新验证')
self.crack()
def close(self):
# 关闭浏览器
self.driver.quit()
上述代码中,通过 get_images()
方法获取验证码中的背景图片和滑块图片,使用 process_image()
方法剪切图片,使用 merge_image()
方法拼接多张图片。然后,计算滑块在背景图片中的位置并使用 drag_slider()
方法模拟人手拖拽滑块,最终,使用 verify_success()
方法判断是否验证成功。
示例说明一
首先进入 极验登录示例页面,切换到“滑动拼图验证码”页签,可以看到本文使用的就是相应的验证方式。执行以下代码:
slider_captcha = SliderCaptcha('https://www.geetest.com/demo/slide')
slider_captcha.crack()
slider_captcha.close()
该代码打开极验登录的示例页面,并自动识别和拖拽验证码进行验证。执行结果如下:
验证成功
可以看到,在自动化执行过程中,程序已完成了验证的全部过程,验证结果为成功。
示例说明二
现在进入 极验官网 的注册页面,该页面需要进行滑动式验证码验证才能完成注册。执行以下代码:
slider_captcha = SliderCaptcha('https://auth.geetest.com/register')
slider_captcha.crack()
slider_captcha.close()
该代码打开极验官网的注册页面,并自动识别和拖拽验证码进行验证。执行结果如下:
验证成功
同样可以看到,程序识别并自动拖拽验证码进行验证,结果也是成功的。
总结
本文介绍了如何使用 Python 实现图片滑动式验证的识别方法。通过使用 Pillow 库来完成图片操作,使用 Selenium 库模拟用户操作浏览器,实现了自动识别和拖拽验证码进行验证。该方法的应用场景非常广泛,有助于提高爬虫和自动化脚本的效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现图片滑动式验证识别方法 - Python技术站