Selenium图片滑块验证码

news2025/1/14 1:24:26

因为种种原因没能实现愿景的目标,在这里记录一下中间结果,也算是一个收场吧。这篇文章主要是用selenium解决滑块验证码的个别案列。

思路:

用selenium打开浏览器指定网站

将残缺块图片和背景图片下载到本地

对比两张图片的相似地方,计算要滑动的距离

规划路线,移动滑块

一、实现步骤

1、用selenium打开浏览器浏览指定网站

1、找到chromedriver.exe的路径

点击开始找到谷歌图标==》右键更多==》打开文件位置==》右键谷歌快捷方式==》属性 ==》打开文件所在的位置 ==》复制路径

2、代码

from selenium import webdriver
 
# chrome_path要改成你自己的路径
 
chrome_path = r"C:\Users\11248\AppData\Local\Google\Chrome\Application\chromedriver.exe"
 
url = 'https://icas.jnu.edu.cn/cas/login'
 
driver = webdriver.Chrome(chrome_path)
 
driver.get(url)

二、将残缺块图片和背景图片下载到本地

1、找到图片位置

打开网页进入开发者工具,找到图片位置

2、代码

import time
 
import requests
 
from PIL import Image
 
from selenium.webdriver.common.by import By
 
from io import BytesIO
 
 
 
time.sleep(5)# 进入页面要停留几秒钟,等页面加载完
 
target_link = driver.find_element(By.CLASS_NAME, "yidun_bg-img").get_attribute('src')
 
template_link = driver.find_element(By.CLASS_NAME, "yidun_jigsaw").get_attribute('src')
 
 
 
target_img = Image.open(BytesIO(requests.get(target_link).content))
 
template_img = Image.open(BytesIO(requests.get(template_link).content))
 
target_img.save('target.jpg')
 
template_img.save('template.png')

三、对比两张图片的相似地方,计算要滑动的距离

1、用matchTemplate获取移动距离

因为背景图片中的残缺块位置和原始残缺图的亮度有所差异,直接对比两张图片相似的地方,往往得不到令人满意的结果,在此要对两张图片进行一定的处理,为了避免这种亮度的干扰,笔者这里将两张图片先进行灰度处理,再对图像进行高斯处理,最后进行边缘检测。

def handel_img(img):
 
    imgGray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)  # 转灰度图
 
    imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1)  # 高斯模糊
 
    imgCanny = cv2.Canny(imgBlur, 60, 60)  # Canny算子边缘检测
 
    return imgCanny

 将JPG图像转变为4通道(RGBA)

def add_alpha_channel(img):
 
    """ 为jpg图像添加alpha通道 """
 
    r_channel, g_channel, b_channel = cv2.split(img)  # 剥离jpg图像通道
 
    alpha_channel = np.ones(b_channel.shape, dtype=b_channel.dtype) * 255  # 创建Alpha通道
 
    img_new = cv2.merge((r_channel, g_channel, b_channel, alpha_channel))  # 融合通道
 
    return img_new

2、代码

import cv2
 
# 读取图像
 
def match(img_jpg_path, img_png_path):
 
    # 读取图像
 
    img_jpg = cv2.imread(img_jpg_path, cv2.IMREAD_UNCHANGED)
 
    img_png = cv2.imread(img_png_path, cv2.IMREAD_UNCHANGED)
 
    # 判断jpg图像是否已经为4通道
 
    if img_jpg.shape[2] == 3:
 
        img_jpg = add_alpha_channel(img_jpg)
 
    img = handel_img(img_jpg)
 
    small_img = handel_img(img_png)
 
    res_TM_CCOEFF_NORMED = cv2.matchTemplate(img, small_img, 3)
 
    value = cv2.minMaxLoc(res_TM_CCOEFF_NORMED)
 
    value = value[3][0]  # 获取到移动距离
 
    return value

3、检验效果

为了验证思路和方法是否得当,这里将滑块图片与背景图片进行拼接,为后面埋下一个小坑。

def merge_img(jpg_img, png_img, y1, y2, x1, x2):
 
    """ 将png透明图像与jpg图像叠加
        y1,y2,x1,x2为叠加位置坐标值
    """
 
    # 判断jpg图像是否已经为4通道
 
    if jpg_img.shape[2] == 3:
 
        jpg_img = add_alpha_channel(jpg_img)
 
    # 获取要覆盖图像的alpha值,将像素值除以255,使值保持在0-1之间
 
    alpha_png = png_img[yy1:yy2, xx1:xx2, 3] / 255.0
 
    alpha_jpg = 1 - alpha_png
 
 
 
    # 开始叠加
 
    for c in range(0, 3):
 
        jpg_img[y1:y2, x1:x2, c] = ((alpha_jpg * jpg_img[y1:y2, x1:x2, c]) + (alpha_png * png_img[yy1:yy2, xx1:xx2, c]))
 
 
 
    return jpg_img
 
    
 
img_jpg_path = 'target.jpg'  # 读者可自行修改文件路径
 
img_png_path = 'template.png'  # 读者可自行修改文件路径
 
x1 = match(img_jpg_path, img_png_path)
 
y1 = 0
 
x2 = x1 + img_png.shape[1]
 
y2 = y1 + img_png.shape[0]
 
# 开始叠加
 
res_img = merge_img(img_jpg, img_png, y1, y2, x1, x2)
 
cv2.imshow("res_img ", res_img)
 
cv2.waitKey(0)

四、规划路线,移动滑块

1、点击滑块移动

用第3节已经获取到的距离,点击滑块进行移动

from selenium.webdriver.support import expected_conditions as EC
 
from selenium.webdriver.support.wait import WebDriverWait
 
from selenium.webdriver import ActionChains
 
 
 
def crack_slider(distance):
 
wait = WebDriverWait(driver, 20)
 
    slider = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'yidun_slider')))
 
    ActionChains(self.driver).click_and_hold(slider).perform()
 
    ActionChains(self.driver).move_by_offset(xoffset=distance, yoffset=0).perform()
 
    time.sleep(2)
 
    ActionChains(self.driver).release().perform()
 
    return 0

神奇的事情是,坑来了,没有匹配成功。

2、匹配失败原因

这里有以下两点原因:

  • 图片尺寸发生了变化,距离要进行转换。

  • 滑块滑动时,滑块和残缺块的相对位置有变动。

首先解决图片尺寸变化问题,找到网页中图片大小:345x172.500

下载到本地图片大小:480x240

所以要对距离进行以下处理:

distance = distance / 480 * 345

关于第二个问题,这里没有找到很好的测量工具测量出来,好在验证码对位置精确度要求不高,就一个个试数吧。

distance = distance /480 * 345 + 12

五、补充

在对极验验证码进行学习中,有的网站对移动轨迹进行了验证,如果滑动太快,也会被识别出机器操作,为了模拟人工操作,出色的程序员写出了一个魔幻移动轨迹

举个例子:我们可以先超过目标,再往回移动。

def get_tracks(distance):
 
     distance += 20
 
     v = 0
 
     t = 0.2
 
     forward_tracks = []
 
     current = 0
 
     mid = distance * 3 / 5
 
     while current < distance:
 
         if current < mid:
 
             a = 2
 
         else:
 
             a = -3
 
         s = v * t + 0.5 * a * (t ** 2)
 
         v = v + a * t
 
         current += s
 
         forward_tracks.append(round(s))
 
 
 
     back_tracks = [-3, -3, -2, -2, -2, -2, -2, -1, -1, -1]
 
     return {'forward_tracks': forward_tracks, 'back_tracks': back_tracks}
 
 
 
 
 
  def crack_slider(tracks):
 
    wait = WebDriverWait(driver, 20)
 
      slider = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'yidun_slider')))
 
      ActionChains(driver).click_and_hold(slider).perform() # 模拟按住鼠标左键
 
 
 
      for track in tracks['forward_tracks']:
 
          ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform()
 
 
 
      time.sleep(0.5)
 
      for back_tracks in tracks['back_tracks']:
 
          ActionChains(driver).move_by_offset(xoffset=back_tracks, yoffset=0).perform()
 
 
 
      ActionChains(driver).move_by_offset(xoffset=-4, yoffset=0).perform()
 
      ActionChains(driver).move_by_offset(xoffset=4, yoffset=0).perform()
 
      time.sleep(0.5)
 
 
 
      ActionChains(driver).release().perform()# 释放左键
 
      return 0

六、完整代码

# coding=utf-8
 
import re
 
import requests
 
import time
 
from io import BytesIO
 
 
 
import cv2
 
import numpy as np
 
from PIL import Image
 
from selenium import webdriver
 
from selenium.webdriver import ActionChains
 
from selenium.webdriver.common.by import By
 
from selenium.webdriver.support import expected_conditions as EC
 
from selenium.webdriver.support.wait import WebDriverWait
 
 
 
 
 
class CrackSlider():
 
    # 通过浏览器截图,识别验证码中缺口位置,获取需要滑动距离,并破解滑动验证码
 
 
 
    def __init__(self):
 
        super(CrackSlider, self).__init__()
 
        self.opts = webdriver.ChromeOptions()
 
        self.opts.add_experimental_option('excludeSwitches', ['enable-logging'])
 
        # self.driver = webdriver.Chrome(ChromeDriverManager().install(), options=self.opts)
 
        chrome_path = r"C:\Users\11248\AppData\Local\Google\Chrome\Application\chromedriver.exe"
 
        self.driver = webdriver.Chrome(chrome_path, options=self.opts)
 
 
 
        self.url = 'https://icas.jnu.edu.cn/cas/login'
 
        self.wait = WebDriverWait(self.driver, 10)
 
 
 
    def get_pic(self):
 
        self.driver.get(self.url)
 
        time.sleep(5)
 
        target_link = self.driver.find_element(By.CLASS_NAME, "yidun_bg-img").get_attribute('src')
 
        template_link = self.driver.find_element(By.CLASS_NAME, "yidun_jigsaw").get_attribute('src')
 
 
 
        target_img = Image.open(BytesIO(requests.get(target_link).content))
 
        template_img = Image.open(BytesIO(requests.get(template_link).content))
 
        target_img.save('target.jpg')
 
        template_img.save('template.png')
 
 
 
    def crack_slider(self, distance):
 
        slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'yidun_slider')))
 
        ActionChains(self.driver).click_and_hold(slider).perform()
 
        ActionChains(self.driver).move_by_offset(xoffset=distance, yoffset=0).perform()
 
        time.sleep(2)
 
        ActionChains(self.driver).release().perform()
 
        return 0
 
 
 
 
 
def add_alpha_channel(img):
 
    """ 为jpg图像添加alpha通道 """
 
 
 
    r_channel, g_channel, b_channel = cv2.split(img)  # 剥离jpg图像通道
 
    alpha_channel = np.ones(b_channel.shape, dtype=b_channel.dtype) * 255  # 创建Alpha通道
 
 
 
    img_new = cv2.merge((r_channel, g_channel, b_channel, alpha_channel))  # 融合通道
 
    return img_new
 
 
 
 
 
def handel_img(img):
 
    imgGray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)  # 转灰度图
 
    imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1)  # 高斯模糊
 
    imgCanny = cv2.Canny(imgBlur, 60, 60)  # Canny算子边缘检测
 
    return imgCanny
 
 
 
 
 
def match(img_jpg_path, img_png_path):
 
    # 读取图像
 
    img_jpg = cv2.imread(img_jpg_path, cv2.IMREAD_UNCHANGED)
 
    img_png = cv2.imread(img_png_path, cv2.IMREAD_UNCHANGED)
 
    # 判断jpg图像是否已经为4通道
 
    if img_jpg.shape[2] == 3:
 
        img_jpg = add_alpha_channel(img_jpg)
 
    img = handel_img(img_jpg)
 
    small_img = handel_img(img_png)
 
    res_TM_CCOEFF_NORMED = cv2.matchTemplate(img, small_img, 3)
 
    value = cv2.minMaxLoc(res_TM_CCOEFF_NORMED)
 
    value = value[3][0]  # 获取到移动距离
 
    return value
 
    
 
 
 
# 1. 打开chromedriver,试试下载图片
 
cs = CrackSlider()
 
cs.get_pic()
 
# 2. 对比图片,计算距离
 
img_jpg_path = 'target.jpg'  # 读者可自行修改文件路径
 
img_png_path = 'template.png'  # 读者可自行修改文件路径
 
distance = match(img_jpg_path, img_png_path)
 
distance = distance /480 * 345 + 12
 
# 3. 移动
 
cs.crack_slider(distance)

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:【文末领取】


     【下面是我整理的2023年最全的软件测试工程师学习知识架构体系图+全套资料】


一、Python编程入门到精通


二、接口自动化项目实战  

三、Web自动化项目实战


四、App自动化项目实战 

五、一线大厂简历


六、测试开发DevOps体系 

七、常用自动化测试工具


八、JMeter性能测试 

九、总结(文末尾部小惊喜)

生命不息,奋斗不止。每一份努力都不会被辜负,只要坚持不懈,终究会有回报。珍惜时间,追求梦想。不忘初心,砥砺前行。你的未来,由你掌握!

生命短暂,时间宝贵,我们无法预知未来会发生什么,但我们可以掌握当下。珍惜每一天,努力奋斗,让自己变得更加强大和优秀。坚定信念,执着追求,成功终将属于你!

只有不断地挑战自己,才能不断地超越自己。坚持追求梦想,勇敢前行,你就会发现奋斗的过程是如此美好而值得。相信自己,你一定可以做到!   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/869757.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

openocd调试esp32(通过FT232H)

之前在学习ESP32&#xff0c;其中有一部分课程是学习openocd通过JTAG调试程序的&#xff0c;因为我用的是ESP32-wroom&#xff0c;usb端口没有集成对应的usb转jtag的ft232&#xff0c;查了ESP32相关的资料&#xff08;JTAG 调试 - ESP32 - — ESP-IDF 编程指南 latest 文档 (es…

【yolov系列:小白yolov7跑数据集建立环境】

首先在github上面获取别人的源码 这个是github的源码包&#xff0c;直接下载解压使用 打开解压后的文件夹应该可以看到这个页面。 进入文件夹的requirements.txt的页面 这篇文章是为了记录自己的环境配置过程&#xff0c;当作笔记使用来看&#xff0c;目前网上各种安装教程都…

微信小程序中键盘弹起输入框自动跳到键盘上方处理

效果展示 键盘未弹起时 键盘弹起后&#xff1a; 实现方式 话就不多说了 我直接贴代码了 原理就是用你点击的输入框的底部 距离顶部的位置 减去屏幕高度除以2&#xff0c;然后设成负值&#xff0c;再将这个值给到最外层相对定位的盒子的top属性&#xff0c;这样就不会出现顶…

linux文件I/O之 fcntl() 函数用法:设置文件的 flags、设置文件锁(记录锁)

头文件和函数声明 #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ ); 函数功能 获取、设置已打开文件的属性 返回值 成功时返回根据 cmd 传递的命令类型的执行结&#xff0c;失败时返回 -1&#xff0c;并设置 errno 为相…

山西电力市场日前价格预测【2023-08-12】

日前价格预测 预测明日&#xff08;2023-08-12&#xff09;山西电力市场全天平均日前电价为330.52元/MWh。其中&#xff0c;最高日前电价为387.00元/MWh&#xff0c;预计出现在19: 45。最低日前电价为278.05元/MWh&#xff0c;预计出现在13: 00。 价差方向预测 1&#xff1a; 实…

【Bert101】最先进的 NLP 模型解释【02/4】

0 什么是伯特&#xff1f; BERT是来自【Bidirectional Encoder Representations from Transformers】变压器的双向编码器表示的缩写&#xff0c;是用于自然语言处理的机器学习&#xff08;ML&#xff09;模型。它由Google AI Language的研究人员于2018年开发&#xff0c;可作为…

最强自动化测试框架Playwright(9)- 下载文件

对于页面下载的每个附件&#xff0c;都会发出 page.on&#xff08;“download”&#xff09; 事件。 下载开始后&#xff0c;将发出下载事件。下载完成后&#xff0c;下载路径将变为可用 所有这些附件都下载到一个临时文件夹中。可以使用事件中的下载对象获取下载 URL、文件系…

BClinux8.6 制作openssh9.2p2 rpm升级包和升级实战

一、背景说明 BClinux8.6 安装的openssh 版本为9.3p1&#xff0c;经绿盟扫描&#xff0c;存在高危漏洞&#xff0c;需要升级到最新。 OpenSSH 命令注入漏洞(CVE-2020-15778) OpenSSH 安全漏洞(CVE-2023-38408) 目前官网只提供编译安装包&#xff0c;而BClinux8.6 为rpm方…

上市公司绿色发展专题:重污染行业企业名单与绿色创新数据

数据简介&#xff1a;上市公司&#xff0c;尤其是重污染行业上市公司实现绿色发展&#xff0c;广泛开展绿色创新&#xff0c;是我国高质量发展的必然要求&#xff0c;受到了来自学界与各级ZF的诸多关注。现有研究中对上市公司绿色发展问题的研究发现&#xff0c;重污染行业上市…

剑指offer14-I.剪绳子

昨天写的那道题是数组中除了一个元素外其余元素的乘积&#xff0c;这道题自然就想到了把一个数分成两个的和&#xff0c;然后积就是这两个数的积&#xff0c;而这两个数中的每个数又可以分成两个数&#xff0c;所以可以用动态规划的方法&#xff0c;dp[i] dp[j]*dp[i-j]。但是…

ChatGPT应用在律师行业需谨慎,南非有律师被它的幻觉误导了!

ChatGPT自去年以来大受欢迎&#xff0c;没想到它这么快会出现在法庭上。 最近&#xff0c;南非约翰内斯堡地区法院审理一个案件时&#xff0c;有律师因为使用ChatGPT生成的虚假参考资料而受到指责。[1] 根据《星期日泰晤士报》的报道&#xff0c;法院判决认为&#xff0c;该名…

pgsql checkpoint机制(1)

检查点触发时机 检查点间隔时间由checkpoint_timeout设置pg_xlog中wall段文件总大小超过参数max_WAL_size的值postgresql服务器在smart或fast模式下关闭手动checkpoint 为什么需要检查点&#xff1f; 定期保持修改过的数据块作为实例恢复时起始位置&#xff08;问题&#xf…

6.利用matlab完成 符号矩阵的秩和 符号方阵的逆矩阵和行列式 (matlab程序)

1.简述 利用M文件建立矩阵 对于比较大且比较复杂的矩阵&#xff0c;可以为它专门建立一个M文件。下面通过一个简单例子来说明如何利用M文件创建矩阵。 例2-2 利用M文件建立MYMAT矩阵。(1) 启动有关编辑程序或MATLAB文本编辑器&#xff0c;并输入待建矩阵&#xff1a;(2) 把…

Python爬虫——requests_cookie登陆古诗文网

寻找登陆需要的参数 __VIEWSTATE:aiMG0UXAfCzak10C7436ZC/RXoZbM2lDlX1iU/4wjjdUNsW8QUs6W2/3M6XIKagQZrC7ooD8Upj8uCnpQMXjDAp6fS/NM2nGhnKO0KOSXfT3jGHhJAOBouMI3QnlpJCQKPXfVDJPYwh169MGLFC6trY __VIEWSTATEGENERATOR: C93BE1AE from: http://so.gushiwen.cn/user/collect.…

springboot异步任务

在Service类声明一个注解Async作为异步方法的标识 package com.qf.sping09test.service;import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service;Service public class AsyncService {//告诉spring这是一个异步的方法Asyncp…

Day 28 C++ (映射)map 容器 / multimap 容器 (多重映射)

文章目录 map (映射)定义注意优点 map构造和赋值构造赋值示例 map大小和交换函数原型示例 map插入和删除函数原型四种插入方式示例 map查找和统计函数原型示例 map容器排序 multimap 容器 (多重映射)定义特点和map的区别示例 map (映射) 定义 C中的map是一种关联容器&#xf…

Windows - UWP - 为UWP应用创建桌面快捷方式

Windows - UWP - 为UWP应用创建桌面快捷方式 前言 这是一个较为简单的方式&#xff0c;不需要过多的命令行。 How 首先Win R -> shell:AppsFolder -> 回车&#xff0c; 这将显示电脑上的已安装应用&#xff08;Win32 & UWP&#xff09;&#xff1a; 找到想要创建…

uniapp使用阿里矢量库

然后解压复制全部到你的项目文件 最后只要这几个 然后引入 最后在你需要的页面使用

多线程的同步与互斥

文章目录 线程安全问题多线程互斥互斥量mutex互斥锁的使用理解锁加锁如何做到原子性对mutex做封装 可重入与线程安全死锁 线程同步条件变量条件变量函数接口理解条件变量条件变量的使用 线程安全问题 首先来看一段代码&#xff0c;该代码是一个多线程抢票的逻辑 #include<…

go的gin和gorm框架实现切换身份的接口

使用go的gin和gorm框架实现切换身份的接口&#xff0c;接收前端发送的JSON对象&#xff0c;查询数据库并更新&#xff0c;返回前端信息 接收前端发来的JSON对象&#xff0c;包含由openid和登陆状态组成的一个string和要切换的身份码int型 后端接收后判断要切换的身份是否低于该…