Python实现滑块拼图验证码详解
本文详细解析Python实现滑块拼图验证码的两种方案。初级版通过解析网页源码中的left属性计算滑动距离;高级版则利用Selenium截图并结合PIL库的ImageChops模块对比有缺与无缺口图像,通过像素差异定位缺口位置。文章提供完整代码及分步滑动技巧,帮助开发者应对不同难度的验证码反爬机制。
滑动拼图验证码作为滑块验证码的进阶形态,其验证逻辑更为复杂。本节内容将深入探讨并实现两种不同难度的滑动拼图验证码:初级版与高级版。

初级版滑块拼图验证码
- 初级版滑动拼图验证码在基础滑块验证之上,增加了随机滑动距离的设定。用户必须依据拼图中缺口的具体位置,来精准控制滑块的最终停留点。
- 如左侧图片所示,这是滑动拼图验证码的初始加载状态,此时界面上尚未显示拼图块与缺口。当用户点击滑块后,拼图和缺口才会显现,如右侧图片所示。我们可以利用这一交互特性,在后台获取拼图与缺口的相对位置信息。

- 接下来开始编写自动化验证代码。首先,使用Selenium库打开目标网页,具体代码如下:
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属性值。该属性值表示缺口左边界距离整张图片左边界的像素距离,示例中为135像素。

如图片所示,采用相同的方法查看拼图元素的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() #释放滑块补充知识点
若需降低滑动速度以避免被检测,可将总滑动距离拆分为三段。让滑块分三次滑动,每次滑动后暂停一定时间,代码如下:
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()
高级版滑动拼图验证码
- 初级版验证码将拼图和缺口的位置信息直接写入网页源代码,攻击者可直接通过解析left属性值计算滑动距离从而通过验证。然而,高级版滑动拼图验证码将缺口信息融合进背景图中,网页源代码中不再包含缺口位置信息,这大大增加了模拟验证的难度。
- 人类识别缺口的方法是比对无缺口图像与有缺口图像的差异。在命令行窗口中执行“pip install pillow”命令即可安装PIL图像处理库。
- 首先,使用Selenium库打开目标网页,代码如下:
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属性值,即圆角矩形左边界到图像左边界的距离,如图片所示:

将前一步获取的坐标值与滑块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滑块拼图验证码内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













