【爬虫】8.1. 使用OCR技术识别图形验证码

news2024/11/25 0:58:01

使用OCR技术识别图形验证码

文章目录

  • 使用OCR技术识别图形验证码
    • 1. OCR技术
    • 2. 准备工作
      • 2.1. tesserocr安装异常
    • 3. 验证码图片爬取
    • 4. 无障碍识别测试
    • 5. 错误识别
    • 6. 识别实战:
    • 7. 参数设置

图形验证码是最早出现的验证方式,现在依然很常见,一般由4位左右的字母或者数字组成。本章节使用的网站时https://captcha7.scrape.center/,这个网站的验证码相对来说比较平整,没有过多的干扰线和干扰点,文字也没有大幅度的变形和旋转,因此比较好作为案例进行分析,对于这类验证码,可以使用OCR技术识别。参考书籍依然是Python3网络爬虫开发实战(第三版)。

1. OCR技术

OCR,即Optical Character Recognition,中文叫做光学字符识别,是指使用电子设备(例如扫描仪和数码相机)检查打印再纸上的字符,通过检查暗、亮的模式确定字符形状,然后使用字符识别方法将形状转化位计算机文字。现在OCR技术已经广泛应用于生产活动中,如文档识别,证件识别,字幕识别,文档搜索等。当然用来识别本节所述的图形验证码也没有问题。

2. 准备工作

再本节的学习中需要导入tesserocr库,这个库的安装需要参考https://setup.scrape.center/tesserocr.另外,还需要安装Selenium、Pillow、Numpy和retrying库用来模拟登录、处理图像和重试操作,可以使用pip3工具安装这些库。 安装好这些库就可以开始了。

2.1. tesserocr安装异常

如果安装异常的话就换一个,可以参照我的,我用的库不是上面的,而是pytesseract,我觉得两者差别不大

  • 打开tesseract下载的网页 tesseract,下载最后一个(应该是)tesseract-ocr-w64-setup-v5.3.0.2.221214这个版本,接着就是安装,安装过程中自己记好自己安装在哪里!!!然后就是选择语言包,建议不要全选会下载很慢。
  • 将你记下来的安装路径的整个文件地址给添加到环境变量中去。
  • 接着python安装pytesseract,找到pytesseract.py文件,打开并找到tesseract_cmd这个变量(大约在30行左右)将里面的值修改为tesseract.exe文件的地址(这个文件在你一开始记下的文件地址里面,查找文件夹就找到了,不用进其他的文件夹,注意转义字符)。
  • 搞定上述之后在cmd窗口运行tesseract --list-langs可以看到你下载的语言包。
  • 重启,然后运行你的示例代码就行了,如果还不可以,那你去看其他下载教程

3. 验证码图片爬取

这个网页使用JavaScript渲染出来的,所以我们进行爬取的时候使用selenium自动化测试工具。

from selenium import webdriver
from selenium.webdriver.common.by import By
from PIL import Image
from io import BytesIO
import time

def demo():
    browser = webdriver.Chrome()
    browser.get("https://captcha7.scrape.center")
    time.sleep(3)
    captcha = browser.find_element(By.CSS_SELECTOR,"#captcha")
    image = Image.open(BytesIO(captcha.screenshot_as_png))
    image.show()

if __name__ == "__main__":
    demo()

这里使用了我很少见的BytesIO,这是一个类,它的功能是读取二进制数据流,而图片就是二进制数据流;还有就是captcha.screenshot_as_png这部分的功能就是将当前页面的内容捕获为一张图像,以bytes二进制数据保存;最后调用image的show方法来显式验证码的图像。

4. 无障碍识别测试

首先我们选用两张图片来进行测试,第一张是有换行和明显空格,第二张是一张验证码。
在这里插入图片描述
在这里插入图片描述

我们运行下面代码:

import pytesseract
from PIL import Image
image1 = Image.open("tesseract_tt1.png")
result1 = pytesseract.image_to_string(image1)
image2 = Image.open("tesseract_tt2.png")
result2 = pytesseract.image_to_string(image2)
print(result1, end= '')
print("=========")
print(result2, end= '')
Demons
Lin
Ss ZzTU
=========
2034

我们可以看到在输出SZTU这部分时候出现了SsZz这样大小写都输出的情况,这是因为pytesseract库在识别大小写字母时候很难准确识别出大小写,你可以采取其他办法来执行,这里就不列出来。

5. 错误识别

我选取到了一张图片,如下所示:
在这里插入图片描述

import pytesseract
from PIL import Image
image = Image.open("error.png")
result = pytesseract.image_to_string(image)
print(result, end= '')
04-8 d.

可以看到这个输出结果明显不是我们想要的,这是因为OCR识别技术是通过检查暗、亮的模式确定字符形状,不是我们想当然的用脑子来看。所以,我们需要做一些额外处理,把干扰信息去掉,我们观察发现,图片里哪些造成干扰的点,其颜色大多比文本的颜色更浅,因此可以通过颜色将干扰点去掉。首先将保存的图片转化为数组,看一下维度:

from PIL import Image
import numpy as np
image = Image.open("error.png")
print(np.array(image).shape)
print(image.mode)
(38, 112, 4)
RGBA

从结果上可以看出,这个图片其实是一个三维数组,38和112代表图片的高和宽,4则是每个像素点的表示向量,那为什么是4呢?因为最后一维是一个长度为4的数组分别表示R(红)G(绿)B(蓝)A(透明度),即一个像素点由4个数字表示。那为什么是RGBA而不是RGB或者其他的呢?因为image.mode是RGBA,即由透明通道的真彩色。

mode属性定义了图片的类型和像素的位宽,一共由9种类型:

  • 1:像素用1位表示,Python中表示为True或False,即二值化。
  • L:像素用8位表示,取值位0-255,表示灰度图像,数字越小,颜色越黑。
  • P:像素用8位表示,即调色板数据。
  • RGB:像素用3X8位表示,即真彩色。
  • RGBA:像素用4X8位标识,即有透明通道的真彩色。
  • CMYK:像素用4X8位表示,即印刷四色模式。
  • YCbCr:像素用3X8位表示,即彩色视频格式。
  • I:像素用32位整型表示。
  • F:像素用32位浮点型表示。

为了方便处理,可以把RGBA转化位更简单的L,即把图片转化位灰度图像。往图片对象的convert方法中传入L即可,代码如下表示:

image = image.convert('L')
image.show()

我们选择把图片转化位灰度图像,然后根据阈值删除图片上的干扰点,成功识别出验证码,代码如下:

from PIL import Image
import numpy as np

image = Image.open("error.png")
image = image.convert('L')
threshold = 90
array = np.array(image)
array = np.where(array> threshold, 255, 0)
image = Image.fromarray((array.astype('uint8')))
# image.show()
result = pytesseract.image_to_string(image)
print(result)

这里先将变量threshold赋值位50.它代表灰度的阈值。接着将图片转化位Numpy数组,利用Numpy的where方法对数组进行筛选和处理,其中将灰度大于阈值的图片的像素设置为255表示白色,否则为0,表示黑色。

6. 识别实战:

import time
import re
import pytesseract
from selenium import webdriver
from io import BytesIO
from PIL import Image
from retrying import retry
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import numpy as np


def preprocess(image):
    image = image.convert('L')
    array = np.array(image)
    array = np.where(array > 105, 255, 0)
    image = Image.fromarray(array.astype('uint8'))
    return image


@retry(stop_max_attempt_number=10, retry_on_result=lambda x: x is False)
def login():
    browser.get('https://captcha7.scrape.center/')
    browser.find_element(By.CSS_SELECTOR, '.username input[type="text"]').send_keys('admin')
    browser.find_element(By.CSS_SELECTOR, '.password input[type="password"]').send_keys('admin')
    captcha = browser.find_element(By.CSS_SELECTOR,'#captcha')
    image = Image.open(BytesIO(captcha.screenshot_as_png))
    image = preprocess(image)
    image.show()
    captcha = pytesseract.image_to_string(image)
    print(captcha)
    captcha = re.sub('[^A-Za-z0-9]', '', captcha)
    browser.find_element(By.CSS_SELECTOR, '.captcha input[type="text"]').send_keys(captcha)
    browser.find_element(By.CSS_SELECTOR, '.login').click()
    try:
        WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//h2[contains(., "登录成功")]')))
        time.sleep(5)
        browser.close()
        return True
    except TimeoutException:
        return False


if __name__ == '__main__':
    browser = webdriver.Chrome()
    login()

7. 参数设置

在使用 pytesseract 时,你可以使用以下参数:

  1. lang: 这个参数用于指定 OCR 使用的语言。默认为 ‘eng’,表示英文。如果你的验证码是英文的,那么你可以保持这个默认值。如果验证码是其他语言的,你需要指定相应的语言代码。例如,中文的语言代码是 ‘chi_sim’。
  2. config: 这个参数用于指定 tesseract 的配置文件。你可以使用它来调整 OCR 的行为。例如,你可以设置 tesseract 只识别数字和大写字母。
  3. nice: 这个参数用于指定 OCR 的质量。值的范围是 0-3,0 表示最快但质量最低,3 表示最慢但质量最高。默认值是 0。如果你的验证码很难识别,你可能需要将这个值设为 3。

这些参数可以在调用 pytesseract.image_to_string 时通过关键字参数的方式指定。例如:

captcha = pytesseract.image_to_string(image, lang='chi_sim', config='--psm 10', nice=3)

另外,你也可以使用 pytesseract.image_to_data 函数,它比 image_to_string 更灵活。image_to_data 函数返回一个包含了 OCR 结果的数据结构,你可以从这个数据结构中提取你需要的信息。例如,你可以提取每个单词的置信度,然后只保留置信度高的单词。

还有其他的识别技巧可以学习,这里给出CSDN博客我觉得挺好的一篇:

借助Tesseract-OCR进行文本检测(1)

借助Tesseract-OCR进行文本检测(2)

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

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

相关文章

【uni-app】

准备工作 1.下载hbuilder,插件使用Vue3的uni-app项目 2.需要安装编译器 3.下载微信开发者工具 4.点击运行->微信开发者工具 5.打开微信开发者工具的服务端口 效果图 page.json(添加路由,修改底层导航栏,背景色&#xff09…

安达发|APS排程系统解决各类制造业难题方案

APS(Advanced Product Scheduling,先进产品计划)软件是一种基于计算机技术的生产计划和调度系统,广泛应用于汽车制造、电子制造、注塑、化工、纺织等行业。本文将详细介绍APS软件在这些行业的应用场景及其优势。 一、汽车制造 1. 零部件生产计划:APS软件…

QEM网格简化算法学习

《Surface Simplification Using Quadric Error Metrics》这篇论文介绍了一种网格简化的算法,通过“edge contraction”(边收缩)的方法来简化网格。边收缩的结果就是将两个顶点合成一个顶点,因此可以按照任意的顶点数目去简化网格…

2023国赛C题解题思路代码及图表:蔬菜类商品的自动定价与补货决策

2023国赛C题:蔬菜类商品的自动定价与补货决策 C题表面上看上去似乎很简单,实际上23题非常的难,编程难度非常的大,第二题它是一个典型的动态规划加仿真题目,我们首先要计算出销量与销售价格,批发价格之间的…

MySQL的概述、版本、安装过程

作者:Insist-- 个人主页:insist--个人主页 作者会持续更新网络知识和python基础知识,期待你的关注 目录 一、MySQL的概述 二、MySQL的版本 三、MySQL的下载与安装 前言 本文将来谈谈MySQL的概述,MySQL的版本,以及它…

浙大MBA提面苏州/上海批周末申请截止:仅剩杭州第五批可选

9月10日一过,2024年浙大MBA提前批面试将正式迎来最后一批申请!还没开始申请的伙伴要抓紧时间了,按照惯例,最后一批一般在时间节奏上都是最为紧张的! 回顾今年的提前批面试申请历程,虽然在总体人数上…

企业内训课程、在线教育平台付费课程加密防下载的10种方式

企业内训课程、在线教育平台付费课程加密防下载的10种方式: 实例演示:课程视频-第1课状语从句,VRM演示应用 企业内训课程、在线教育平台付费课程,他们的这种视频课程的加密是如何做的?整理了10种思路,供大家参考&…

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

日前价格预测 预测明日(2023-09-09)山西电力市场全天平均日前电价为372.85元/MWh。其中,最高日前电价为435.72元/MWh,预计出现在18: 45。最低日前电价为342.46元/MWh,预计出现在04: 00。 价差方向预测 1: 实…

UMA 2 - Unity Multipurpose Avatar☀️二.概念介绍

文章目录 🟥 UMA核心🟧 UMA Data 数据类1️⃣ DNA2️⃣ Slots 插槽Overlays 纹理贴图🟨 Base Recipe 基础人形Recipes🟩 Wardrobe Recipes 服饰Recipes🟥 UMA核心 UMA核心组件是 DynamicCharacterAvatar ,后续我们跟插件交互的API,例如捏脸的参数,都是与之交互完成的…

element-ui switch开关组件二次封装,添加loading效果,点击时调用接口后改变状态

先看效果: element-ui中的switch开关无loading属性(在element-plus时加入了),而且点击时开关状态就会切换,这使得在需要调用接口后再改变开关状态变得比较麻烦。 思路:switch开关外包一层div,给…

SAP FI/SD的集成-VKOA科目确定

前言 一、组成部分 二、使用步骤 1.VKOA确定收入科目 1.1定义物料科目分配组 1.2定义客户科目分配组 2.V/08定价过程 3. 库存成本Inventory的自动记账科目配置-OBYC 总结 前言 财务和销售集成的点,也是各种SAP顾问经常遇到的面试问题,实际工作中也会经常…

雅思 《九分达人》阅读练习(二)

目录 雅思阅读练习 《九分达人》test3 paragraph3 1.单词含义要记准确,敏感度要上来。 2.找准定位,之后理解句子大致含义。 说说关于判断题的做题方法 关于“承认”有哪些单词 同替词汇 think 可以用什么其他单词来替换 单词 一些疑问 I have…

项目实战:ES的增加数据和查询数据

文章目录 背景在ES中增加数据新建索引删除索引 在ES中查询数据查询数据总数量 项目具体使用(实战)引入依赖方式一:使用配置类连接对应的es服务器创建配置类编写业务逻辑----根据关键字查询相关的聊天内容在ES中插入数据 总结提升 背景 最近需…

每日一题(设计循环队列)

每日一题(设计循环队列) 622. 设计循环队列 - 力扣(LeetCode) 1.题意解读 本题只能为队列开辟k个单位空间,并且只能利用这几个空间进行数据的存储。 思路:本题使用数组来实现队列是比较方便的&#xff0c…

Unity WebView 中文输入支持

WebView 中文输入支持 🥪效果展示🍱原理 🥪效果展示 💡使用版本为4.4; 💡测试环境:unity editor 2022.3.15f1c1、Windows; 🍱原理 提取页面激活的输入框,…

代码随想录第29天 | ● 1005.K次取反后最大化的数组和 ● 134. 加油站 ● 135. 分发糖果

1005.K次取反后最大化的数组和 var largestSumAfterKNegations function(nums, k) {while(k>0){nums.sort((a,b)>a-b);nums[0]-nums[0];k--}return nums.reduce((prev, cur)>prevcur,0) };第一想法 每次换最小的那个数,负数换正数,正数换负数…

python+vue+django九价疫苗预约系统

疫苗预约的效率,取代人工管理是必然趋势。 本九价疫苗预约系统以Django作为框架,B/S模式以及MySql作为后台运行的数据库。本系统主要包括以下功能模块:用户、医生、医院、九价疫苗、疫苗预约、系统管理等模块,通过这些模块的实现能…

三门问题讨论

三门问题讨论 三门问题第一种第二种 三门问题 三门问题(Monty Hall problem)亦称为蒙提霍尔问题、蒙特霍问题或蒙提霍尔悖论,大致出自美国的电视游戏节目Let’s Make a Deal。问题名字来自该节目的主持人蒙提霍尔(Monty Hall&…

二分查找 - 二分答案

第四部分 二分答案 最小值最大(或最大值最小)问题,二分答案区间,配合贪心、DP 等其他算法检验这个答案是否合理,最优化问题转换为 判定性问题。 「二分」的本质是二段性,并非单调性。说白了就是答案在一个区间,二分区间,直到找到最优答案。 TreeSet 的方法: E floor​…

Zstack 安装 黑群晖未找到硬盘:解决方法

错误原因: 发生错误的原因,黑群晖要求硬盘为Sata格式,而默认创建的硬盘格式为Virtio,我们要做的就是修改挂载的虚拟硬盘改为Sata格式 解决方法: 1、进入 ZStack,找到黑群晖的主机,查看 UUID …