Python实现滑块拼图验证码详解
作者:Triumph19 发布时间:2022-04-28 23:22:26
滑动拼图验证码可以算是滑块验证码的进阶版本,其验证机制相对复杂。本节将介绍两种滑动拼图验证码:初级版和高级版本。
初级版滑块拼图验证码
初级版滑动拼图验证码是在普通滑块验证码的基础上增加了随机的滑动距离,用户需要根据拼图的缺口位置来决定滑块的滑动位置。
如下左图所示为一个滑块拼图验证码的起始状态,注意此时还没有显示拼图和缺口。单击滑块后就会出现拼图和缺口,如下右图所示。之后会利用这一特性来找到拼图和缺口的位置。
下面开始编写代码。首先用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() #释放滑块
补充知识点
如果不希望滑动得太快,可以将滑动距离分为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()
高级版滑动拼图验证码
初级版滑动拼图验证码将拼图和缺口的位置都写在网页源代码中,我们可以直接根据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属性值,也就是圆角矩形的左边界到图像的左边界的距离,如下图所示:
将前面获取的两个距离相减,就是滑块需要移动的距离。下面来移动滑块,代码如下:
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() #释放滑块
运行结果如下,可以看到成功地通过了验证
来源:https://blog.csdn.net/Triumph19/article/details/124571914
猜你喜欢
- 细线边框是网页中定位区分内容常用的一种方法,配合特定图片的使用,往往能够达到不错的效果,那么如何制作细线边框呢?asp之家注:现在要实现这个
- 抓取“xmly”鬼故事音频import json # 在这个url,音频链接为JSON动态生成,所以用到了json模块impor
- 前言:如果正在看文章的你,还不会绘制折线图,请看如何使用matplotlib绘制折线图这篇文章,该文章会仔细而详尽的告诉你绘制折线图的方法。
- 好记星不如烂笔头,适时的总结梳理知识让人更轻松愉快。今天总结下学习和开发中遇到的JavaScript执行顺序的问题,今天挖个坑,以后会慢慢填
- 本文中介绍的主要是SQL语句,请大家不要在Access中使用。SQL的分类:DDL—数据定义语言(CREATE,ALTE
- 情况一:坐标上的内容是文字时如上图这样一个横向的柱状图,y坐标轴的内容太长后会导致显示不全。因为数据是由后端传过来的,有些会很长有些会比较短
- 项目开发中文件的读写是必不可少的下面来简单介绍一下文件的读读文件,首先我们要有文件那我首先自己创建了一个文本文件password.txt内容
- 支持CSS属性Safari和WebKit实施大子的CSS 2.1规格所界定的万维网联盟( W3C ) ,以及部分的CSS 3规格。 。这个C
- 1.数据是什么?在 Python 以及其他所有面向对象编程语言中,类都是对数据的构成(状态)以及数据 能做什么(行为)的描述。由于类的使用者
- 官方文档:需求:当1个job启动构建后,获取它的构建状态.(成功,失败,驳回,构建中,正在排队)关键函数:获取job是否在排队的结果获取正在
- 本文出自“Python为什么”系列,归档在 Github 上:https://github.com/chinesehuazhou/pytho
- 方法一:利用Cookies对象 因为Cookies对象把变量的值保存在浏览器客户端,所以可以根据Cookies保存的IsVoted的值来判断
- 先说下自己的环境,redis是部署在centos上的,爬虫运行在windows上,1. 安装redisyum install -y redi
- PyQ5已经自动定义了很多QT自建的信号。但是在实际的使用中为了灵活使用信号与槽机制,可以根据需要自定义信号。通过使用pyqtSignal(
- 1.根据id获取元素document.getElementById("id属性的值");返回值是一个元素对象案例:点击按
- 1、GIL简介GIL的全称为Global Interpreter Lock,全局解释器锁。1.1 GIL设计理念与限制python的代码执行
- 简介zhdate模块统计从1900年到2100年的农历月份数据代码,支持农历和公历之间的转化,并且支持日期差额运算。安装pip instal
- URL是可以添加变量部分的,把类似的部分抽象出来,比如:@app.route('/example/1/')@app.rout
- 理论傅立叶变换用于分析各种滤波器的频率特性,对于图像,2D离散傅里叶变换(DFT)用于找到频域.快速傅里叶变换(FFT)的快速算法用于计算D
- 1.echo和print的区别PHP中echo和print的功能基本相同(输出),但是两者之间还是有细微差别的。echo输出后没有返回值,但