算术图片验证码(四则运算)+selenium

一、表达式解析

这里假设已经识别出来表达式,如何识别验证码图片里的表达式,放在下面讲。涉及到的正则表达式的解析放在本篇文章最后面。


import re
# 表达式解析(支持小数的 +-*/ 和中文运算符)
def parse_math_expression(text):# 替换中文运算符为英文text = text.replace('加', '+').replace('减', '-').replace('乘', '*').replace('除', '/')text = text.replace('x', '*').replace('X', '*').replace('÷', '/')# 正则表达式提取表达式中的数字和运算符# match = re.search(r'(\d+)\s*([+\-*/]|加|减|乘|除)\s*(\d+)', text)match = re.search(r'(\d+(?:\.\d+)?)\s*([+\-*/]|加|减|乘|除)\s*(\d+(?:\.\d+)?)', text) # 可匹配小数if not match:return Nonenum1, operator, num2 = match.groups()try:num1 = float(num1)num2 = float(num2)# 计算结果if operator == '+':result = num1 + num2elif operator == '-':result = num1 - num2elif operator == '*':result = num1 * num2elif operator == '/':result = num1 / num2else:return None# 要么返回整数,要么返回最多两位小数,round()四舍六入五平分,如果五平分的进位不对,刷新页面重新识别吧,懒得处理了return int(result) if result.is_integer() else round(result, 2)except:return None# 调试用
ocr_result = "9.1加3.2等于"result = parse_math_expression(ocr_result)
if result is not None:print(f"计算结果: {result}")else:print("无法解析表达式")

二、配合selenium

#!/usr/bin/env python
# encoding: utf-8from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import ddddocr
import re# 表达式解析(支持 +-*/ 和中文运算符)
def parse_math_expression(text):# 替换中文运算符为英文text = text.replace('加', '+').replace('减', '-').replace('乘', '*').replace('除', '/')text = text.replace('x', '*').replace('X', '*').replace('÷', '/')# 正则表达式提取表达式中的数字和运算符# match 对象包含匹配成功的信息,若未匹配到则返回 None# match = re.search(r'(\d+)\s*([+\-*/]|加|减|乘|除)\s*(\d+)', text) #匹配整数match = re.search(r'(\d+(?:\.\d+)?)\s*([+\-*/]|加|减|乘|除)\s*(\d+(?:\.\d+)?)', text) # 可匹配小数if not match:return Nonenum1, operator, num2 = match.groups() #groups()	仅包含捕获组,索引从 0 开始,如('3.14', '乘', '2.71')try:num1 = float(num1)num2 = float(num2)# 计算结果if operator == '+':result = num1 + num2elif operator == '-':result = num1 - num2elif operator == '*':result = num1 * num2elif operator == '/':result = num1 / num2else:return None# 要么返回整数,要么返回最多两位小数,round()四舍六入五平分,如果五平分的进位不对,刷新页面重新识别吧return int(result) if result.is_integer() else round(result, 2)except:return None# 配置浏览器
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(5)# 打开验证码页面
driver.get('http://127.0.0.1/1.html')
time.sleep(2)  # 等待页面加载# 获取验证码图片
captcha_element = driver.find_element(By.ID, 'captcha')
captcha_png = captcha_element.screenshot_as_png# 初始化 OCR 引擎(支持中文运算符)
ocr = ddddocr.DdddOcr(show_ad=False)
# OCR 识别
ocr_result = ocr.classification(captcha_png)
print(f"OCR 识别结果: {ocr_result}")# 计算表达式结果
# ocr_result = '9.14加3.15等于' # debug使用
result = parse_math_expression(ocr_result)if result is not None:print(f"计算结果: {result}")# 自动填写结果(假设输入框 ID 为 'captcha_input')input_element = driver.find_element(By.ID, 'captcha_input')input_element.send_keys(str(result))# 提交表单(假设按钮 ID 为 'submit')submit_button = driver.find_element(By.ID, 'submit')submit_button.click()print("已提交表单")
else:print("无法解析表达式")# 等待用户查看结果后关闭浏览器
time.sleep(5)
driver.quit()

三、引申:正则表达式搭配group()

group() 是 Python 正则表达式模块 re 中用于提取匹配结果的核心方法,必须与正则表达式的匹配对象(Match 对象)搭配使用。

1. group()基本定义

  • match.group(n):返回正则表达式中第 n 个捕获组的匹配内容。
  • match.group(0):返回整个匹配的字符串(即正则表达式匹配到的完整文本)。
import retext = "今天是2023-06-07"
regex = r'(\d{4})-(\d{2})-(\d{2})'  # 三个捕获组:年、月、日
match = re.search(regex, text)if match:print(match.group(0))  # 整个匹配: "2023-06-07"print(match.group(1))  # 第一个捕获组: "2023"print(match.group(2))  # 第二个捕获组: "06"print(match.group(3))  # 第三个捕获组: "07"

注意:match.groups()跟match.group()是不一样的,groups()返回内容仅包含捕获组(即括号()中定义的内容),不包含整个匹配结果。上面的算术代码用的是groups()。

2. 例子中的正则表达式解析

(1)(\d+(?:.\d+)?) 匹配整数或小数

部分含义示例匹配
\.匹配小数点(. 需要转义).
\d+匹配 1 个或多个数字14、5
(?:...)非捕获组(不创建分组)仅用于分组,不保存结果
?前面的内容可选(0 次或 1 次).14、空字符串

(2)空白字符 \s*

  • \s:匹配任意空白字符(空格、制表符、换行等)
  • *:匹配 0 次或多次(即可有可无)

(3)运算符部分 ([+-*/]|加|减|乘|除)

  • 逻辑或 |:分隔多个可选模式,匹配其中任意一个
  • 分组 ():捕获匹配的内容,便于后续提取 [ ] :字符组,匹配其中任意一个字符
  • 需要转义(-),否则表示范围(如 [0-9])
  • +、* 理论上需要转义,但多数引擎允许不转义

四、用到的验证码识别库ddddocr

DdddOcr 带带弟弟OCR通用验证码离线本地识别SDK免费开源版
(链接包含各种强大用法的使用文档,感兴趣可看,如下图)
在这里插入图片描述

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

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

相关文章

使用 Laravel 中的自定义存根简化工作

在开发与外部服务、API 或复杂功能交互的应用程序时,测试几乎总是很困难。简化测试的一种方法是使用存根类。以下是我通常使用它们的方法。 福利简介 存根是接口或类的伪实现,用于模拟真实服务的行为。它们允许您: 无需调用外部服务即可测试…

将 tensorflow keras 训练数据集转换为 Yolo 训练数据集

以 https://www.kaggle.com/datasets/vipoooool/new-plant-diseases-dataset 为例 1. 图像分类数据集文件结构 (例如用于 yolov11n-cls.pt 训练) import os import csv import random from PIL import Image from sklearn.model_selection import train_test_split import s…

排序算法-归并排序与快速排序

归并排序与快速排序 快速排序是利用的递归思想:选取一个基准数,把小于基准数的放左边 大于的放右边直到整个序列有序 。快排分割函数 O(lognn), 空间 :没有额外开辟新的数组但是递归树调用函数会占用栈内存 O(logn) 。 归并排序:在递归返回的…

北大开源音频编辑模型PlayDiffusion,可实现音频局部编辑,比传统 AR 模型的效率高出 50 倍!

北大开源了一个音频编辑模型PlayDiffusion,可以实现类似图片修复(inpaint)的局部编辑功能 - 只需修改音频中的特定片段,而无需重新生成整段音频。此外,它还是一个高性能的 TTS 系统,比传统 AR 模型的效率高出 50 倍。 自回归 Tra…

MyBatis————入门

1,配置相关 我们上一期详细讲了一下使用注解来实现操作数据库的方式,我们今天使用xml来实现,有同学可能有疑问,使用注解挺方便呀,为啥还要注解呀,先来说一下注解我感觉挺麻烦的,但是我们后面要…

【推荐算法】推荐算法演进史:从协同过滤到深度强化学习

推荐算法演进史:从协同过滤到深度强化学习 一、传统推荐时代:协同过滤的奠基(1990s-2006)1.1 算法背景:信息爆炸的挑战1.2 核心算法:协同过滤1.3 局限性 二、深度学习黎明:神经网络初探&#xf…

Java基于SpringBoot的校园闲置物品交易系统,附源码+文档说明

博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…

Ajax Systems公司的核心产品有哪些?

Ajax Systems 是一家专注于家庭安全和智能系统的公司,其核心产品如下3: 入侵保护设备:如 MotionCam Outdoor 无线室外运动探测器,配备内置摄像头和两个红外传感器,可通过预装电池运行长达三年,能在 15 米距…

64、js 中require和import有何区别?

在 JavaScript 中,require 和 import 都是用于模块导入的语法,但它们属于不同的模块系统,具有显著的区别: 1. 模块系统不同 require 属于 CommonJS 模块系统(Node.js 默认使用)。 语法:const…

Java+Access综合测评系统源码分享:含论文、开题报告、任务书全套资料

JAVAaccess综合测评系统毕业设计 一、系统概述 本系统采用Java Swing开发前端界面,结合Access数据库实现数据存储,专为教育机构打造的综合测评解决方案。系统包含学生管理、题库管理、在线测评、成绩分析四大核心模块,实现了测评流程的全自…

【python】RGB to YUV and YUV to RGB

文章目录 1、YUV2、YUV vs RGB3、RGB to YUV4、YUV to RGB附录——YUV NV12 vs YUV NV21参考1、YUV YUV 颜色空间,又常被称作 YCbCr 颜色空间,是用于数字电视的颜色空间,在 ITU-R BT.601、BT.709、BT.2020 标准中被明确定义,这三种标准分别针对标清、高清、超高清数字电视…

运行示例程序和一些基本操作

欢迎 ----> 示例 --> 选择sample CTRL B 编译代码 CTRL R 运行exe 项目 中 Shadow build 表示是否 编译生成文件和 源码是否放一块 勾上不在同一个地方 已有项目情况下怎么打开项目 方法一: 左键双击 xxx.pro 方法二: 文件菜单里面 选择打开项目

计算机网络第2章(下):物理层传输介质与核心设备全面解析

目录 一、传输介质1.1 传输介质的分类1.2 导向型传输介质1.2.1 双绞线(Twisted Pair)1.2.2 同轴电缆(Coaxial Cable)1.2.3 光纤(Optical Fiber)1.2.4 以太网对有线传输介质的命名规则 1.3 非导向型传输介质…

PHP文件包含漏洞详解:原理、利用与防御

PHP文件包含漏洞详解:原理、利用与防御 什么是文件包含漏洞? 文件包含漏洞是PHP应用程序中常见的安全问题,当开发者使用包含函数引入文件时,如果传入的文件名参数未经严格校验,攻击者就可能利用这个漏洞读取敏感文件…

5.4.2 Spring Boot整合Redis

本次实战主要围绕Spring Boot与Redis的整合展开,首先创建了一个Spring Boot项目,并配置了Redis的相关属性。接着,定义了三个实体类:Address、Family和Person,分别表示地址、家庭成员和个人信息,并使用Index…

java内存模型JMM

Java 内存模型(Java Memory Model,JMM)定义了 Java 程序中的变量、线程如何和本地内存以及主内存进行交互的规则。它主要涉及到多线程环境下的共享变量可见性、指令重排等问题,是理解并发编程中的关键概念。 核心概念&#xff1a…

配置git命令缩写

以下是 Git 命令缩写的配置方法及常用方案,适用于 Linux/macOS/Windows 系统: 🔧 一、配置方法 1. 命令行设置(推荐) # 基础命令缩写 git config --global alias.st status git config --global alias.co che…

准确--k8s cgroup问题排查

k8s cgroup问题排查 6月 06 17:20:39 k8s-node01 containerd[1515]: time"2025-06-06T17:20:39.42902033408:00" levelerror msg"StartContainer fo r \"46ae0ef9618b96447a1f28fd2229647fe671e8acbcec02c8c46b37051130c8c4\" failed" error&qu…

Go 中 map 的双值检测写法详解

Go 中 map 的双值检测写法详解 在 Go 中,if char, exists : pairs[s[i]]; exists { 是一种利用 Go 语言特性编写的优雅条件语句,用于检测 map 中是否存在某个键。让我们分解解释这种写法: 语法结构解析 if value, ok : mapVariable[key]; …

C# Wkhtmltopdf HTML转PDF碰到的问题

最近碰到一个Html转PDF的需求,看了一下基本上都是需要依赖Wkhtmltopdf,需要在Windows或者linux安装这个可以后使用。找了一下选择了HtmlToPDFCore,这个库是对Wkhtmltopdf.NetCore简单二次封装,这个库的好处就是通过NuGet安装HtmlT…