Python实战 | 滑块拼图验证码高级版详解

1、如何实现滑块拼图验证码高级版?

在这里插入图片描述

2、HTML代码:

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">

  <title>滑动拼图验证码高级版</title>
    <link href="css/jigsawCanvas.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">

  </head>
  <body>
    <div class="col-md-4">
        <div class="jigsaw" id="jigsaw">
            <div class="imagebox" id="imagebox">
                <canvas width="380" height="260" id=jigsawCanvas></canvas>
                <div class="missblock" id="missblock"></div>
            </div>
            <div class="jigsawTrack" id="jigsawTrack">
                <span class="jigsawCircle" id="jigsawCircle"></span>
                <span class="jigsawTips" id="jigsawTips"><-合并滑块,完成拼图</span>
            </div>
        </div>
    </div>
	
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
    <script scr='js/jquery-3.1.1-min.js'></script>
    <script src='js/jigsawCanvas.js'></script>
  </body>
</html>

3、Python代码:

from selenium import webdriver
import os
import time
from PIL import Image, ImageChops

# 1.访问网址
browser = webdriver.Chrome()
# url = r'E:\验证码反爬\高级滑动拼图验证码\index.html'  # 自己用的话可以直接写这样的固定路径
current_dir = os.path.dirname(os.path.abspath(__file__))  # 获取代码所在的文件夹目录
url = current_dir + '/index.html'  # 获取HTML文件的文件绝对路径
print('此时的文件路径为:' + url)  # 打印此时的文件路径,所以如果文件位置固定,可以直接写url = r'文件路径'
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') # 打开原始图片
image_b = Image.open('after.png') # 打开有缺口的图片
#print(image_a)
#print(image_b)
x = ImageChops.difference(image_a, image_b).getbbox()  # 比较两个图片的差别
print(x)  # 举个例子:倘若x为:(226, 103, 277, 154);返回缺口对应的左边横坐标(由左往右看),上边纵坐标(由上往下看),右边横坐标,下边纵坐标
distance = x[0]  # 第一个元素x[0]表示的就是缺口左边横坐标,也就是滑块需要移动的距离
print(distance)  # 如果例子为:(226, 103, 277, 154),那么需要移动的距离为226

# 5.开始滑动!
action = webdriver.ActionChains(browser)  # 启动Selenium的动作链
action.click_and_hold(slider).perform()  # 按住滑动按钮不松开
action.move_by_offset(distance-10, 0)  # 开始滑动!这里-10,是把初始圆角矩形左侧left属性值给减去了,这样更准确
action.release().perform()  # 释放滑块

4、执行后报错,解决方案:

None
Traceback (most recent call last):
File "E:/tech/a.py", line 28, in <module>
distance = x[0]  # 第一个元素x[0]表示的就是缺口左边横坐标,也就是滑块需要移动的距离
KeyboardInterrupt
Process finished with exit code 1

查找资料发现是

对于Image.open()函数默认真彩图像读取通道顺序为RGB,而cv2.imread()则是BGR。同时,当图像格式为RGBA时,Image.open(‘—.jpg’)读取的格式为RGBA(其中A表示图像的alpha通道,即RGBA共四个通道),而cv2.imread(‘—.jpg’)读取的格式是BGR,只有三个通道
要加上:

image_a = Image.open('origin.png').convert('RGB')  # 打开原始图片
image_b = Image.open('after.png').convert('RGB')  # 打开有缺口的图片

5、完整代码,修改后如下:

from selenium import webdriver
import os
import time
from PIL import Image, ImageChops

# 1.访问网址
browser = webdriver.Chrome()
# url = r'E:\验证码反爬\高级滑动拼图验证码\index.html'  # 自己用的话可以直接写这样的固定路径
current_dir = os.path.dirname(os.path.abspath(__file__))  # 获取代码所在的文件夹目录
url = current_dir + '/index.html'  # 获取HTML文件的文件绝对路径
print('此时的文件路径为:' + url)  # 打印此时的文件路径,所以如果文件位置固定,可以直接写url = r'文件路径'
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')  # 打开有缺口的图片
#print(image_a)
#print(image_b)
x = ImageChops.difference(image_a, image_b).getbbox()  # 比较两个图片的差别
print(x)  # 举个例子:倘若x为:(226, 103, 277, 154);返回缺口对应的左边横坐标(由左往右看),上边纵坐标(由上往下看),右边横坐标,下边纵坐标
distance = x[0]  # 第一个元素x[0]表示的就是缺口左边横坐标,也就是滑块需要移动的距离
print(distance)  # 如果例子为:(226, 103, 277, 154),那么需要移动的距离为226

# 5.开始滑动!
action = webdriver.ActionChains(browser)  # 启动Selenium的动作链
action.click_and_hold(slider).perform()  # 按住滑动按钮不松开
action.move_by_offset(distance-10, 0)  # 开始滑动!这里-10,是把初始圆角矩形左侧left属性值给减去了,这样更准确
action.release().perform()  # 释放滑块

执行后验证通过:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/superdangbo/article/details/128408733