当前位置: 首页 > news >正文

Selenium 实现图片验证码识别

前言

在测试过程中,有的时候登录需要输入图片验证码。这时候使用Selenium进行自动化测试,怎么做图片验证码识别?本篇内容主要介绍使用Selenium、BufferedImage、Tesseract进行图片 验证码识别。

环境准备

jdk:1.8
tessdata:文章末尾附下载地址

安装Tesseract

我本地是ubuntu系统

sudo apt install tesseract-ocr
sudo apt install libtesseract-dev 

在项目中引用

<dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>4.5.4</version>
</dependency>

实现

在下图中,登录需要使用图片验证码进行验证。我们的图片验证码识别流程是使用Selenium定位到图片验证码元素,将元素截图保。然后将保存的图片验证码使用BufferedImage进行灰度化、二值化处理,处理完成后去除图片上的干扰点。最后使用Tesseract进行图片验证码上的字符识别。
在这里插入图片描述

处理图片

首先使用BufferedImage读取图片验证码图片,然后调整亮度后进行灰度化、二值化处理。处理后的图片去除干扰点。

public static void cleanLinesInImage(File sfile, String destDir)  throws IOException{File destF =new File(destDir);if (!destF.exists()){destF.mkdirs();}BufferedImage bufferedImage = ImageIO.read(sfile);int h = bufferedImage.getHeight();int w = bufferedImage.getWidth();// 灰度化int[][] gray = new int[w][h];for (int x = 0; x < w; x++){for (int y = 0; y < h; y++){int argb = bufferedImage.getRGB(x, y);// 图像加亮(调整亮度识别率非常高)int r = (int) (((argb >> 16) & 0xFF) * 1.1 + 30);int g = (int) (((argb >> 8) & 0xFF) * 1.1 + 30);int b = (int) (((argb >> 0) & 0xFF) * 1.1 + 30);//                int r = (int) (((argb >> 16) & 0xFF) * 0.1 + 30);//                int g = (int) (((argb >> 8) & 0xFF) * 0.1 + 30);//                int b = (int) (((argb >> 0) & 0xFF) * 0.1 + 30);if (r >= 255){r = 255;}if (g >= 255){g = 255;}if (b >= 255){b = 255;}gray[x][y] = (int) Math.pow((Math.pow(r, 2.2) * 0.2973 + Math.pow(g, 2.2)* 0.6274 + Math.pow(b, 2.2) * 0.0753), 1 / 2.2);}}ImageIO.write(bufferedImage, "jpg", new File(destDir, sfile.getName()));// 二值化int threshold = ostu(gray, w, h);BufferedImage binaryBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);for (int x = 0; x < w; x++){for (int y = 0; y < h; y++){if (gray[x][y] > threshold){gray[x][y] |= 0x00FFFF;} else{gray[x][y] &= 0xFF0000;}binaryBufferedImage.setRGB(x, y, gray[x][y]);}}ImageIO.write(binaryBufferedImage, "jpg", new File(destDir, sfile.getName()));//        去除干扰线条for(int y = 1; y < h-1; y++){for(int x = 1; x < w-1; x++){boolean flag = false ;if(isBlack(binaryBufferedImage.getRGB(x, y))){//左右均为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x-1, y)) && isWhite(binaryBufferedImage.getRGB(x+1, y))){flag = true;}//上下均为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x, y+1)) && isWhite(binaryBufferedImage.getRGB(x, y-1))){flag = true;}//斜上下为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x-1, y+1)) && isWhite(binaryBufferedImage.getRGB(x+1, y-1))){flag = true;}if(isWhite(binaryBufferedImage.getRGB(x+1, y+1)) && isWhite(binaryBufferedImage.getRGB(x-1, y-1))){flag = true;}if(flag){binaryBufferedImage.setRGB(x,y,-1);}}}}// 矩阵打印//        for (int y = 0; y < h; y++)//        {//            for (int x = 0; x < w; x++)//            {//                if (isBlack(binaryBufferedImage.getRGB(x, y)))//                {//                    System.out.print("*");//                } else//                {//                    System.out.print(" ");//                }//            }//            System.out.println();//        }ImageIO.write(binaryBufferedImage, "jpg", new File(destDir, sfile.getName()));}

OCR识别

setDataPath方法,传入你下载的

public static String executeTess4J(String imgUrl){String ocrResult = "";try{ITesseract instance = new Tesseract();instance.setDatapath("your tessdata path");instance.setLanguage("eng");instance.setOcrEngineMode(0);instance.setTessVariable("tessedit_char_whitelist", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890");File imgDir = new File(imgUrl);//long startTime = System.currentTimeMillis();ocrResult = instance.doOCR(imgDir);}catch (TesseractException e){e.printStackTrace();}return ocrResult;
}

验证

编写Selenium脚本

public static void main(String[] args) throws IOException {System.setProperty("webdriver.chrome.driver", "/home/zhangkexin/chromedriver");WebDriver driver = new ChromeDriver();driver.manage().window().maximize();driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);driver.get("https://xkczb.jtw.beijing.gov.cn/#");WebElement element = driver.findElement(By.xpath("//*[@id=\"getValidCode\"]/img"));File img = element.getScreenshotAs(OutputType.FILE);String path = System.getProperty("user.dir");cleanLinesInImage(img, path);String imgFile = path  + "/" + img.getName();Path source = Paths.get(imgFile);Path dest =  Paths.get("/home/zhangkexin/ui-test/autoTest/img.jpg");Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);String code = executeTess4J("/home/zhangkexin/ui-test/autoTest/img.jpg");System.out.println(code);driver.quit();
}

看一下经过处理后的图片验证码
在这里插入图片描述
最后实际识别出来的结果。
在这里插入图片描述
testdata:
链接:https://pan.baidu.com/s/1uJE9wl1oa2WAsBTsydUlmg?pwd=m576 
提取码:m576

相关文章:

Selenium 实现图片验证码识别

前言 在测试过程中&#xff0c;有的时候登录需要输入图片验证码。这时候使用Selenium进行自动化测试&#xff0c;怎么做图片验证码识别&#xff1f;本篇内容主要介绍使用Selenium、BufferedImage、Tesseract进行图片 验证码识别。 环境准备 jdk&#xff1a;1.8 tessdata&…...

基于云原生向量数据库 PieCloudVector 的 RAG 实践

近年来&#xff0c;人工智能生成内容&#xff08;AIGC&#xff09;已然成为最热门的话题之一。工业界出现了各种内容生成工具&#xff0c;能够跨多种模态产生多样化的内容。这些主流的模型能够取得卓越表现&#xff0c;归功于创新的算法、模型规模的大幅扩展&#xff0c;以及海…...

内存泄漏的影响

(1)内存泄漏是什么&#xff1f; 内存泄漏是指程序运行过程中分配的内存没有被正确释放&#xff0c;导致这部分内存无法再次使用&#xff0c;从而造成内存资源的浪费。内存泄漏可能会导致系统性能下降、程序崩溃或者消耗过多的系统资源&#xff1b;内存泄漏通常发生在动态分配的…...

shell变量扩展你知道多少?

1. shell变量扩展 我们知道&#xff0c;${var}的形式可以获取变量var的值&#xff0c;但其实还可以有更多花式玩法。其中&#xff5e;表示用户根目录其实属于 波浪线扩展&#xff0c;这比较常见&#xff0c;不展开介绍了。 下面的每种情况中&#xff0c;word 都要经过波浪线扩…...

Compose中对于KeyEvent的处理

在开发Android TV时&#xff0c;遇到了一个需求&#xff0c;需要对遥控器发出的上下左右按键点击事件做处理。此处我们可以在Modifier.onKeyEvent中对按键事件做处理。此处我写了一个按钮的modifier模板如下。 private val buttonModifier Modifier.onKeyEvent {when {KeyEve…...

OpenXR Monado compositor处理应用layers(cheduled->delivered)

OpenXR Monado compositor处理应用的layer,scheduled->delivered @src/xrt/targets/common/target_instance.c t_instance_create_system @src/xrt/compositor/main/comp_compositor.ccomp_main_create_system_compositor@src/xrt/compositor/multi/comp_multi_system…...

leetcode:1137 Tribonacci 数列

1137 Tribonacci 数列 题目链接https://leetcode.cn/problems/n-th-tribonacci-number/ 题目描述 Tribonacci 数列是一种类似于斐波那契数列的数列&#xff0c;不同之处在于&#xff0c;Tribonacci 数列中的每一项是前面三项的和。给定整数 n&#xff0c;求出 Tribonacci 数…...

简单讲一下API的作用以及介绍

API全称Application Programming Interface&#xff0c;即应用程序编程接口&#xff0c;是一些预先定义的函数&#xff0c;或指软件系统不同组成部分衔接的约定&#xff0c;用于传输数据和指令&#xff0c;使应用程序之间可以集成和共享数据资源。 API 接口简介 一、基本概念…...

猎板道出PCB免费打样真相:制造成本究竟给了谁?

猎板PCB作为电路板特殊定制的厂家&#xff0c;曾经推出了PCB免费打样活动以吸引新客户。从经营的角度来看&#xff0c;免费打样的成本实际上最终由稳定客户承担。免费打样的客户往往仅在有免费机会时下单&#xff0c;而稳定的合作客户则为这些促销活动买单。这种模式长期下来可…...

Linux 竞争与并发(学习总结)

在Linux驱动开发中&#xff0c;“并发”和“竞争”是两个重要的概念&#xff0c;它们涉及到多任务环境下资源的管理和使用。 并发 (Concurrency) 并发指的是在同一时间段内&#xff0c;多个任务看似同时运行的现象。实际上&#xff0c;在单核处理器上&#xff0c;这通常是通过…...

SaaS初创企业需求建模指南

所以你已经准备好进入市场&#xff0c;你有宏大的目标&#xff0c;并且充满激情。 但等等。 你要如何 实现 这些目标呢&#xff1f; 你设置了 正确的 目标吗&#xff1f; 而且你的目标是 可实现的吗&#xff1f; 那么&#xff0c;如何回答这些问题呢&#xff1f; 进入需求…...

MySQL最左匹配原则

MySQL索引的加左原则&#xff0c;也被称为最左匹配原则&#xff08;Leftmost Prefix Rule&#xff09;或最左前缀规则&#xff08;Leftmost Prefixes&#xff09;&#xff0c;是指在创建复合索引时&#xff0c;应将经常用于查询的列放在索引的最左边&#xff0c;以便MySQL能够更…...

日常开发1:居中处理

开发的时候总会遇到两个空间上下两层,然后居中排放,如果只是知道下方或者上方控件的具体位置点,但是不知道另外一个控件的集体点位,应该怎么处理呢? 如上图所示,知道imageview 下方中间的点的位置(这里暂时定义image的宽高已知),上方是textview,那么如何布局呢? 简单解决方法…...

css弹性盒子——flex布局

目录 ​编辑 一、flex容器的样式属性(父元素属性) display:flex 弹性盒子&#xff0c;实现水平排列,在父盒子设置&#xff0c;适用于单行/单列 justify-content 二、flex元素的样式属性(子元素属性) 1.flex-grow 2.flex-shrink 3.flex-basis 4.flex组合属性 flex:flex-…...

亚马逊云科技 Gen BI 2024-09-04 上海站QuickSight

机缘 我又来了&#xff0c;感觉不上班比上班还要忙 天天像特种工一天&#xff0c;今天有度过的充实的一天&#xff0c;上午去图书馆&#xff0c;下午去了 亚马逊云科技 Gen BI 技术体验日 。 具体照片可以去 这里看 哈哈&#xff0c;这个就是我了 商业智能的趋势 根据艾瑞咨…...

【Qt】Qt和JavaScript使用QWebChannel交互

问题 问题一&#xff1a; 问题描述&#xff1a;运行时&#xff0c;Qt向Js端发送消息没有问题&#xff0c;Js端向Qt端发送消息时失败 报错&#xff1a;Cannot invoke unknown method of index -1 on object webTransport(0x…) 原因及解决办法&#xff1a;使用Qt 5.11.2编译生…...

码住!15个爆好用知识库软件工具分享

市场趋势&#xff1a;全球知识库管理软件的市场规模发展速度非常快&#xff0c;并且未来几年内仍将继续保持增长。据Verified Market Research预测&#xff0c;2028年知识库管理软件的全球市场份额将增长到588.1亿美元&#xff0c;复合年增长率达12.67%。 知识库软件可以帮助企…...

MybatisPlus中@EnumValue注解介绍、应用场景和示例代码

EnumValue注解详细介绍 功能概述&#xff1a; EnumValue注解标记在枚举类型的字段上&#xff0c;表示该字段是枚举值在数据库中存储的实际值。这对于枚举的持久化是关键&#xff0c;确保枚举在数据库中的表示与Java枚举类的一致性。 主要用途&#xff1a; 字段指定&#xff1a;…...

【计算机网络】描述TCP建立连接与断开的过程

一、TCP连接的建立与断开 1、建立连接——三次握手 1、A的TCP向B发出连接请求报文段 其首部中的同步位SYN 1&#xff0c;并选择序号seq x&#xff0c;表明传送数据时的第一个数据字节的序号是 x 2、B的TCP收到连接请求报文段后&#xff0c;如同意&#xff0c;则发回确认。 B …...

CSS学习14[重点]

定位 前言一、定位二、定位模式1. 静态定位 static2. 相对定位 relative3. 绝对定位 absolute4. 子绝父相5. 绝对定位的盒子水平居中 6. 固定定位&#xff08;fixed&#xff09;7. 叠放次序&#xff08;z&#xff09;三、四种定位总结四、定位模式转换 前言 为什么学习定位&am…...

我让 Claude 和 Codex 同时审计 个模块,它们只在 个上达成共识识

整体排查思路 我们的目标是验证以下三个环节是否正常&#xff1a; 登录成功时&#xff1a;服务器是否正确生成了Session并返回了包含正确 JSESSIONID的Cookie给浏览器。 浏览器端&#xff1a;浏览器是否成功接收并存储了该Cookie。 后续请求&#xff1a;浏览器在执行查询等操作…...

CMake的project()命令,除了起名字还能干啥?一个例子讲透VERSION和DESCRIPTION的妙用

CMake的project()命令&#xff1a;从命名到项目管理的进阶实践 CMake作为现代C/C项目构建的事实标准&#xff0c;其project()命令往往是每个CMakeLists.txt文件的开篇之作。大多数开发者仅将其视为项目命名的工具&#xff0c;却忽略了它作为项目元数据中心枢纽的潜力。本文将深…...

IP地址什么?工业场景网络注意事项有哪些?僬

OCP原则 ocp指开闭原则&#xff0c;对扩展开放&#xff0c;对修改关闭。是七大原则中最基本的一个原则。 依赖倒置原则&#xff08;DIP&#xff09; 什么是依赖倒置原则 核心是面向接口编程、面向抽象编程&#xff0c; 不是面向具体编程。 依赖倒置原则的目的 降低耦合度&#…...

“INMS: Memory Sharing for Large Language Model based Agents“ 论文笔记誓

1.概述在人工智能快速发展的今天&#xff0c;AI不再仅仅是回答问题的聊天机器人&#xff0c;而是正在演变为能够主动完成复杂任务的智能代理。OpenAI的Codex CLI就是这一趋势的典型代表——一个跨平台的本地软件代理&#xff0c;能够在用户的机器上安全高效地生成高质量的软件变…...

NISSHINBO日清纺 NJW4104U2-05A-TE1 SOT-89-5 线性稳压器(LDO)

特性通过AEC-Q100 1级认证&#xff08;仅T1规格&#xff09;低静态电流&#xff1a;典型值5.5μA&#xff08;A版本&#xff09;&#xff0c;典型值5.0μA&#xff08;B版本&#xff09;工作电压4.0V至40V工作温度Ta -40C至125C输出电压精度&#xff1a;V0 1.0%&#xff08;T…...

C++的constinit常量初始化与静态存储期变量的启动时间优化

C的constinit常量初始化与静态存储期变量的启动时间优化 在现代C开发中&#xff0c;程序的启动性能优化是一个不可忽视的课题。尤其是静态存储期变量&#xff08;如全局变量或静态局部变量&#xff09;的初始化&#xff0c;往往会导致程序启动时间延长。为了解决这一问题&…...

从零到精通:全面掌握AI大模型的系统学习路径,大模型时代掌握未来,抢占AI风口!

本文介绍了人工智能领域的大型预训练模型——大模型&#xff0c;解释了其工作原理和应用场景&#xff0c;如自然语言处理、内容推荐、教育和辅助学习、医疗和健康护理等。文章还探讨了学习大模型的意义&#xff0c;包括技术趋势、就业市场、解决问题能力、创新能力等方面。此外…...

AI时代新型的项目管理应该是什么样的?嗣

AI训练存储选型的演进路线 第一阶段&#xff1a;单机直连时代 早期的深度学习数据集较小&#xff0c;模型训练通常在单台服务器或单张GPU卡上完成。此时直接将数据存储在训练机器的本地NVMe SSD/HDD上。 其优势在于IO延迟最低&#xff0c;吞吐量极高&#xff0c;也就是“数据离…...

FreeRTOS任务跑飞别慌!教你用PSP和uxTaskGetStackHighWaterMark锁定罪魁祸首

FreeRTOS任务跑飞排查实战&#xff1a;从PSP追踪到栈溢出的全链路分析 当你在深夜调试一个复杂的FreeRTOS项目时&#xff0c;突然发现某个任务毫无征兆地崩溃进入HardFault_Handler——这种经历对嵌入式开发者来说简直如同噩梦。与裸机环境不同&#xff0c;RTOS的多任务特性让问…...

GeoAI赋能智慧城市:从交通优化到环境监测的实战解析

1. GeoAI如何让城市交通更聪明 每天早上7点半&#xff0c;北京西二旗地铁站的人流就像开了闸的洪水。但你可能不知道&#xff0c;现在这些拥挤的站台正在被一种叫GeoAI的技术悄悄改变。简单来说&#xff0c;GeoAI就是让地图会思考的魔法——它把人工智能装进了地理信息系统&…...