python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python滑块拼图验证码

Python实现滑块拼图验证码详解

作者:Triumph19

验证码作为一种自然人的机器人的判别工具,被广泛的用于各种防止程序做自动化的场景中。传统的字符型验证安全性已经名存实亡的情况下,各种新型的验证码如雨后春笋般涌现,今天给大家分享一篇Python实现滑块验证码

滑动拼图验证码可以算是滑块验证码的进阶版本,其验证机制相对复杂。本节将介绍两种滑动拼图验证码:初级版和高级版本。

初级版滑块拼图验证码

from selenium import webdriver
browser =webdriver.Chrome()
url = r'D:\works\python_crawl1\《Python爬虫(进阶与进通)》代码汇总\2.验证码反爬\4.滑动拼图验证码\滑动拼图验证码初级\index.html'
browser.get(url) #用模拟浏览器打开网页
slider = browser.find_element_by_xpath('//*[@id="slideBtn"]') #定位滑块
slider.click() # 模拟单击滑块,让拼图和缺口显现出来
time.sleep(3) #等待3秒

如下图所示,用同样的方法查看拼图的left属性值,即拼图的左边界到整张图片的左边界的距离,这里为2像素。

因为拼图的初始left属性值始终为2像素,所以只需要提取缺口的left属性值。这里用正则表达式来提取,代码如下:

import re
data = browser.page_source #获取网页源代码
p_qk = '<div class="slide-box-shadow".*?left: (.*?)px' #编写正则表达式
qk_left = re.findall(p_qk,data,re.S) #提取缺口的left属性值

获得qk_left如下:

将缺口和拼图的left属性值相减,就可以得到滑块需要滑动的距离,代码如下:

distance = float(qk_left[0]) - float(2) #用float()函数将数据都切换为浮点数(即带小数点的数)

计算结果如下:

计算出滑动距离后,用2.3节讲解的方法进行模拟滑动即可,代码如下:

action = webdriver.ActionChains(browser) # 启动动作链
action.click_and_hold(slider).perform() #按住滑块
action.move_by_offset(distance,0) #移动滑块,其中的distance是之前计算出来的需要滑动的距离,第二个参数0则为y轴方向移动的距离,因为这里不需要y轴方向移动,所以为设置为0
action.release().perform() #释放滑块

完整代码如下:

# 完整代码如下
import time
from selenium import webdriver
# 1.访问网址
browser =webdriver.Chrome()
url = r'D:\works\python_crawl1\《Python爬虫(进阶与进通)》代码汇总\2.验证码反爬\4.滑动拼图验证码\滑动拼图验证码初级\index.html'
browser.get(url) #用模拟浏览器打开网页
# 2.定位滑块并模拟单击,让缺口显现出来
slider = browser.find_element_by_xpath('//*[@id="slideBtn"]') #定位滑块
slider.click() # 模拟单击滑块,让拼图和缺口显现出来
time.sleep(3) #等待3秒
# 3.获得缺口位置
data = browser.page_source #获取网页源代码
p_qk = '<div class="slide-box-shadow".*?left: (.*?)px' #编写正则表达式
qk_left = re.findall(p_qk,data,re.S) #提取缺口的left属性值
print(qk_left)
# 4.计算滑块需要滑动的距离
distance = float(qk_left[0]) - float(2) #用float()函数将数据都切换为浮点数(即带小数点的数)
print(distance)
# 5.开始滑动
action = webdriver.ActionChains(browser) # 启动动作链
action.click_and_hold(slider).perform() #按住滑块
action.move_by_offset(distance,0) #移动滑块,其中的260是之前计算出来的需要滑动的距离
action.release().perform() #释放滑块

补充知识点

如果不希望滑动得太快,可以将滑动距离分为3段,让滑块分3次滑动,每次滑动后等待一定时间,代码如下:

x1 = distance / 3
x2 = x1
x3 = distance - x1 - x2
action.move_by_offset(x1,0)
time.sleep(1)
action.move_by_offset(x2,0)
time.sleep(1)
action.move_by_offset(x3,0)
time.sleep(1)
action.release().perform()

高级版滑动拼图验证码

from selenium import webdriver
browser = webdriver.Chrome()
url = r'D:\works\python_crawl1\《Python爬虫(进阶与进通)》代码汇总\2.验证码反爬\4.滑动拼图验证码\滑动拼图验证码高级\index.html'
browser.get(url) #用模拟浏览器打开网页

通过XPath表达式定位验证码原始图片,截图并保存,代码如下:

browser.find_element_by_xpath('//*[@id="jigsawCanvas"]').screenshot('origin.png') #截图无缺口图像

截取到的无缺口图像如下图所示:

接着模拟单击滑块,会出现缺口,再次截图并保存,代码如下:

slider = browser.find_element_by_xpath('//*[@id="jigsawCircle"]') #定位滑块
slider.click() #模拟单击滑块,让图像出现缺口
browser.find_element_by_xpath('//*[@id="jigsawCanvas"]').screenshot('after.png') #截取有缺口的图片

截取到的有缺口图像如下图所示:

可以看到,无缺口图像和有缺口图像知识缺口处不同,其他地方完全相同。对比两幅图像的像素,将不同的像素找出来,就能知道缺口的位置。PIL库提供的ImageChops模块可以对比两幅图像的异同,并给出缺口的位置。通过如下代码从PIL库中导入需要使用的模块:

from PIL import Image,ImageChops

用Image模块中的open()函数打开要对比的两张截图,代码如下:

image_a = Image.open('origin.png').convert('RGB')
image_b = Image.open('after.png').convert('RGB')

接着用ImageChops模块中的difference()函数对比两张截图的像素,并获取不同之处的坐标值(注意,这种验证码的缺口位置每次都会变化,所以每次获得的坐标值也不一样)代码如下:

x = ImageChops.difference(image_a,image_b).getbbox()
print(x)

(261, 21, 313, 72)

getbbox()函数会以元组的形式返回缺口的一组坐标值。

distance = x[0] #第1个元素为缺口的左边界到图像的左边界的距离
distance

接着用开发者工具查看白色圆角矩形的left属性值,也就是圆角矩形的左边界到图像的左边界的距离,如下图所示:

将前面获取的两个距离相减,就是滑块需要移动的距离。下面来移动滑块,代码如下:

action = webdriver.ActionChains(browser) # 启动动作链
action.click_and_hold(slider).perform() #按住滑块
action.move_by_offset(distance-10,0) #移动滑块,其中的260是之前计算出来的需要滑动的距离
action.release().perform() #释放滑块

完整代码如下:

from selenium import webdriver
import time
from PIL import Image,ImageChops
# 1.访问网址
browser = webdriver.Chrome()
url = r'D:\works\python_crawl1\《Python爬虫(进阶与进通)》代码汇总\2.验证码反爬\4.滑动拼图验证码\滑动拼图验证码高级\index.html'
browser.get(url) #用模拟浏览器打开网页
time.sleep(2)
# 2.获取无缺口图像
browser.find_element_by_xpath('//*[@id="jigsawCanvas"]').screenshot('origin.png') #截图无缺口图像
# 3.获取有缺口图像
slider = browser.find_element_by_xpath('//*[@id="jigsawCircle"]') #定位滑块
slider.click() #模拟单击滑块,让图像出现缺口
browser.find_element_by_xpath('//*[@id="jigsawCanvas"]').screenshot('after.png') #截取有缺口的图片
# 4.比较两幅图像,获取需要移动的距离
image_a = Image.open('origin.png').convert('RGB')
image_b = Image.open('after.png').convert('RGB')
x = ImageChops.difference(image_a,image_b).getbbox()
print(x)
distance = x[0] #第1个元素为缺口的左边界到图像的左边界的距离
distance
# 5.开始滑动
action = webdriver.ActionChains(browser) # 启动动作链
action.click_and_hold(slider).perform() #按住滑块
action.move_by_offset(distance-10,0) #移动滑块,其中的260是之前计算出来的需要滑动的距离
action.release().perform() #释放滑块

运行结果如下,可以看到成功地通过了验证

到此这篇关于Python实现滑块拼图验证码详解的文章就介绍到这了,更多相关Python滑块拼图验证码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文