【成长笔记】图片验证码识别

破解携程中文验证码爬取机票价格数据 selenium+webdriver轻松绕过携程反爬虫验证码,重点是中文点选问题,涉及到中文识别OCR技术,使用开源社区的chineseocr_lite,一款轻量级中文OCR项目,完美解决中文识别问题。 阅读详情

记得很早以前,我对如携程飞猪等第三方平台购买火车票不用输入验证码感到很……牛!百度后发现其可能是实现了自动打码,或者说机器自动识别验证码,我很好奇。

后来,当我觉得我必须要给自己找些有趣的知识来学习的时候,脑海里萌生了去实现一个简单的验证码识别程序的想法。在一切未知以前,我觉得很难,甚至望而却步。但,真正一点点地行动下来,我发现,其实慢慢深入后,无论多么困难的问题,都能一点点解决。

不要着急,不要慌张,一点点地啃下来,一个方式不通,换个思路解决,不要轻易放弃。这个过程中,世上无难事,只怕有心人,古人诚不欺我。任何事情,流于表面而不做,是永远不会成长的——谨以告诫自己。 

好了,废话不多说。

-----------------------------------------------------我是萌萌的分割线--------------------------------------------------------准备:

  • 语言:python
  • python库:opencv,sklearn,requests等

流程:整体大致流程为四部分,预处理,字符分割,字符标记分类,字符识别

  • 预处理:对原始验证码图片进行如灰度处理,二值化,降噪等处理,为下一步的字符分割提供一个好的素材
  • 字符分割:将预处理后的图片中的每个字符单独分割出来,本次分割的图片比较取巧,当预处理后,图片中各个字符的位置是相对固定的,所以,采用的分割方法为等距分割。
  • 字符标记分类:当字符分割好后,需要人为为字符进行分类标记,这个过程属于体力活,比较繁琐。我尝试过直接调用谷歌的ocr(光学字符识别)工具库pytesseract来代替人工识别,但是结果非常不好,无奈,还是只能先人工仔细分类。
  • 字符识别:分类好后,图片经过二值化转换为01的数据,写入一个txt格式文件中,作为训练集,其结果类似如下所示:
图片转换为可训练的数字文本数据

再利用机器学习算法对之进行训练,本文使用的是经典的svm(支持向量机)算法对图片验证码进行训练。支持向量机的原理以及优势百度谷歌均可详细查到。

实现:

  • 获取图片验证码

巧妇难为无米之炊,首先,我们要有原材料。在网上,我们可以很轻易地找到图片验证码。本文找的是csdn上的图片验证码。当然了,我们需要的验证码素材至少也要百张以上吧。如果傻乎乎地鼠标刷新保存图片,那效率太低了。要充分利用好可以利用的工具,python中的url库,requests库等都是很强大的工具库。用来爬取网络资源数据可以说是无往不利,哈哈,莫笑我略装*哈~

# coding=utf8
import requests

res = requests.get('img_code_url') # 这是一个get请求,获取图片资源
with open(file_path + "/%d.jpg" % num, "wb") as f: # 将图片保存在本地
    f.write(res.content)
    print("%d" % num + "获取成功")

如何获取图片验证码呢,我们可以利用浏览器的开发者模式(一般F12快捷键即可打开)或者利用专业的抓包软件如Charles(收费)等来查看获取。以上是个简单地将网上的图片验证码保存到本地的程序代码。

如果我们选择的图片验证码本身是十分清晰的没有太多混淆的状态,我们可以考虑用pytesseract直接对它进行识别。比如此类图片:

可以看出,以上这张图片验证码并未经过太多复杂处理,文本清晰,所以可以很容易ocr直接识别。但是如此类验证码则不然:

可以看出,这类验证码被经过了很多噪声处理,很多像素点在混淆,如果不经过处理直接用ocr识别会很糟糕。

  • 图片预处理

对图片进行灰度化,二值化,等距切割。

# coding=utf8
import cv2

def pre_img(file_name):  # 图片灰度,二值化处理
   img = cv2.imread(file_name, 0)
   img = cv2.threshold(img, 180, 255, 1)

以上是对图片进行灰度化以及二值化的处理程序,利用的opencv库,opencv的使用方法可以看它的官方文档,或者百度搜索相应的博客等等。

然后,图片变成这样的了:

我们可以看出,此时图片上依然存在许多混淆的噪点,所以我们需要将这个噪点给去掉。通过观察图片,多数噪点是孤立的,非联通的,所以我们可以根据噪点周边的区域存在点的个数来判断其是否为噪点。

# coding=utf8
import numpy as np

# 计算像素周边的点的个数
def sum_9_region(img, x, y):
    cur_pixel = img.getpixel((x, y))  # 当前像素点的值
    width = img.width
    height = img.height

    if cur_pixel == 255:  # 如果当前点为白色区域,则不统计邻域值
        return 10

    if y == 0:  # 第一行
        if x == 0:  # 左上顶点,4邻域
            # 中心点旁边3个点
            sum = cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y + 1))
            return 4 - sum / 255
        elif x == width - 1:  # 右上顶点
            sum = cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y + 1))

            return 4 - sum / 255
        else:  # 最上非顶点,6邻域
            sum = img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y + 1)) \
                  + cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y + 1))
            return 6 - sum / 255
    elif y == height - 1:  # 最下面一行
        if x == 0:  # 左下顶点
            # 中心点旁边3个点
            sum = cur_pixel \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y - 1)) \
                  + img.getpixel((x, y - 1))
            return 4 - sum / 255
        elif x == width - 1:  # 右下顶点
            sum = cur_pixel \
                  + img.getpixel((x, y - 1)) \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y - 1))

            return 4 - sum / 255
        else:  # 最下非顶点,6邻域
            sum = cur_pixel \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x, y - 1)) \
                  + img.getpixel((x - 1, y - 1)) \
                  + img.getpixel((x + 1, y - 1))
            return 6 - sum / 255
    else:  # y不在边界
        if x == 0:  # 左边非顶点
            sum = img.getpixel((x, y - 1)) \
                  + cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x + 1, y - 1)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y + 1))

            return 6 - sum / 255
        elif x == width - 1:  # 右边非顶点
            # print('%s,%s' % (x, y))
            sum = img.getpixel((x, y - 1)) \
                  + cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x - 1, y - 1)) \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y + 1))

            return 6 - sum / 255
        else:  # 具备9领域条件的
            sum = img.getpixel((x - 1, y - 1)) \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y + 1)) \
                  + img.getpixel((x, y - 1)) \
                  + cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x + 1, y - 1)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y + 1))
            return 9 - sum / 255

# 去除噪点
def clear_noise(img):
    filename = './temp/clear_noise/' + str(random.random()) + '.png'
    x, y = img.width, img.height
    for i in range(x):
        for j in range(y):
            if sum_9_region(img, i, j) <= 2:
                # print(img.getpixel((i,j)))
                img.putpixel((i, j), 255)
    img = np.array(img)

以上程序实现的是当一个黑色像素点周边8个像素位置上小于或等于2个黑色像素点的情况,认定其为孤立的噪点,将它去除,则获得以下图片:

图片验证码的噪点被除去了。 

接下来,要对其进行字符分割的处理,在这里,看出图片是一个很规整的,所以,简单地采用等距分割即可分割开。最后分割的图片如下:

以上是图片预处理的全过程,那么,要对验证码进行训练,一张图片是肯定不够的,所以,我们得批量下载几百张图片验证码。对它进行预处理,然后标记分类,最终得到以下结果(因为此类图片验证码只有0-9,所以分类为10类):

以上是其中分类为0的文件夹中的一部分数据,至此,分类完成。

  • 图片训练 

将图片转换为01矩阵的形式。

import cv2

def get_binary_pix(img):
    img = cv2.imread(img, 0)
    img = cv2.threshold(img, 180, 1, 1)
    img_binary = img.tolist()
    img_binary.append('label')
    pixs = [str(i) for i in img_binary]
    content = ','.join(pixs)
    with open("train_data.txt", "a+") as f:
        f.write(content)

利用sklearn库的svm算法对之进行训练。

from sklearn.svm import SVC

def train():
    dataset = load_data()
    raw, col = dataset.shape
    X = dataset[:, :col - 1]
    Y = dataset[:, -1]
    clf = SVC()
    clf.fit(X, Y)
    jl.dump(clf, 'model.pkl')

至此,训练完毕,模型建立好了。此时,再下载几个验证码进行测试,同样,对测试验证码进行预处理等流程。

测试结果很理想。

至此,图片验证码识别完成。

---------------------------------------------------我是萌萌的分割线--------------------------------------------------------

在开始实现之前,心里其实很不确定最后是否可以真的实现出来,但是,不懂就要去查,百度,谷歌,博客,书籍,等等方式,感谢公网上的开放的知识,让我学到了很多很多。

源码已传github上:

portfloat/captcha_recgithub.com图标

,欢迎大家clone。写得不好,欢迎大家批评指正,谢谢~


【愚公系列】《Python网络爬虫从入门到精通》046-验证码识别(字符验证码) 在之前的内容中,我们已经学习了如何使用Python进行各类网络爬虫的编写与优化。然而,在实际的爬虫项目中,我们经常会遇到验证码的挑战,它是阻止自动化程序访问的重要手段之一。本篇文章,我们将深入探讨验证码识别中的一种常见类型——字符验证码。验证码识别是爬虫自动化中的一项重要技能,掌握它将大大提升我们的爬虫项目的效率和成功率。验证码的基本原理:了解验证码的作用和常见类型。字符验证码识别的基本方法:从简单的图像处理到使用OCR(光学字符识别)技术。实战:使用Python和相关库进行字符验证码识别。 阅读详情

相关推荐

用Python模拟识别图片验证码并发送手机验证码_python训练识别图片验证码(3)

不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~给大家准备的学习资料包括但不限于:Python 环境、pycharm编辑器/永久激活/翻译插件python 零基础视频教程Python 界面开发实战教程Python 爬虫实战教程Python 数据分析实战教程python 游戏开发实战教程Python 电子书100本。

m0_60707708的博客 688

携程滑块,点选文字识别

code_datawhale05_xiecheng.py 携程滑块,点选文字识别 from selenium import webdriver from selenium.webdriver import ActionChains import time import base64 from PIL import Image from aip import AipOcr """ https:/...

酒逢知己千杯少,欢迎驾临 3708

【愚公系列】《Python网络爬虫从入门到精通》047-验证码识别(第三方验证码识别)

在爬虫开发中,验证码是我们需要面对的一个挑战,尤其是当我们遇到更加复杂的验证码时,如何识别它们成为了一个难题。本篇文章,我们将讨论如何使用第三方验证码识别服务来突破这一障碍。相比传统的图像处理与OCR技术,第三方验证码识别服务提供了更为高效和精准的解决方案。通过调用这些服务,我们可以大大简化验证码识别的流程,提升爬虫的自动化程度。第三方验证码识别服务概述:了解市面上常见的第三方验证码识别服务及其优势。如何使用Python调用第三方验证码识别API:讲解如何接入这些服务,并进行验证码的自动识别。

愚公智库 10万+

JS逆向入门案例-x程滑块、点选验证码+登录+phantom-token -17

JS逆向入门案例-x程滑块、点选验证码+登录+phantom-token -17

qq_53444631的博客 4211

pytorch入门攻略及项目实战之卷积神经网络进行验证码识别

文章目录 一.前言 二.知识储备(基于个人理解) 三.爬取数据 四.数据处理 五.定义、训练、测试神经网络 六.可视化处理与后续应用 一.前言 疫情仍然严重,写完上一篇博客后我也从零开始学习神经网络,真实绕了很多弯路啊。。这网上资料多归多,有用的属实难找,再加上之前忙美赛,转眼就隔了两周才有进展,这里非常想把自己从一个什么都不懂的小白一步步成长到可以自己定义、训练神经网络的大白之路分享给所有想要入...

namespace_Pt的博客 2711

【人工智能】图像识别之小白天书——验证码篇(1)

本文介绍了图像识别领域应用到验证码破解中的第一课,以一种极简的,学习成本极低的方式,带你初识AI,初识图像识别。

JDJRdata的博客 1万+

【python爬虫实战】:不同验证码的自动识别

你有没有想过,当你在填写登录表单时,为什么会有验证码?为什么它们有时候那么复杂,让人头大?而有时候又显得那么弱智?今天,我们一起探讨一下如何用 Python 爬虫识别各种验证码,让你的爬虫项目自由冲浪!

Python栈 1万+

Jmeter(二十):jmeter对图片验证码的处理_jmeter图片验证码code uuid

在json提取器中通过jsonpath方法提取出code的值。识别图片验证码的字段为json格式;

egregw的博客 546

Jmeter验证码图片识别注册接口压力测试实战_压测时,登录需要传图形验证码

添加BeanShell Sample,编写以下脚本,脚本的功能为导入jar包,并且识别路径“D:\code\vcode_src\8.jpeg”中的图片验证码的值。大概的图片识别处理步骤是:设置字符的识别方式是英文和数字,将图片按区域识别每一个字符,把每一个字符截取下来,做灰度处理以及锐化,并且把这个字符对应区域的图片放大。代码完成的功能为,输入验证码图片的路径,输出验证码图片的识别结果,结果是一个字符串类型。// 请求体,captcha为图片验证码的值,func为请求接口,mobile为手机号。

2301_82244608的博客 1635

Python图片验证码降噪 — 8邻域降噪_python 图片怎么去除横线的干扰

🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化学习资料的朋友,可以戳这里获取。

m0_61549984的博客 911

携程新版图标点选验证码识别

携程的图标分类识别依然换谈不换药,不管使用哪种开源模型进行迁移训练即可,标题可能为3个,可能为4个,并且标题含有通明通道,动态识别标题即可,识别效果如下。注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路。如有侵犯,请联系作者下架。

码王吴彦祖的博客 411

**深度探索:基于CNN的验证码图片识别**

深度探索:基于CNN的验证码图片识别 一、项目简介 如果你正寻找一个强大且易于上手的图像识别项目,用于学习或应用卷积神经网络(CNN),那么“基于CNN的验证码图片识别”项目绝对是你的首选。这一开源项目不仅提供了详尽的指导教程,还封装了两种流行的CNN架构——AlexNet和LeNet,使得你在面对不同难度的验证码图片时,能够灵活选择合适的模型进行训练。 开发人员表示,从2016年至2020年期间...

gitblog_00423的博客 939

易语言实现亦思验证码识别技术教程

易语言是一种以中文为基础的编程语言,其特点在于使用中文作为编程关键字,降低了编程的学习难度,尤其适合中文母语的编程新手。易语言自2000年由吴涛等人推出以来,经历了快速的发展与版本迭代,逐步增加了对面向对象编程、网络编程、数据库操作等高级功能的支持。其发展也伴随着易语言社区的成长,大量基于易语言开发的软件和库使得易语言应用范围不断扩大。亦思验证码模块是易语言社区开发的一款用于验证码识别的库,它支持多种验证码类型,如字符型、数字型以及较为复杂的图像型验证码识别。

weixin_35835030的博客 1538

20行 Python 代码实现简单验证码识别_nii图像二值化

不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~给大家准备的学习资料包括但不限于:Python 环境、pycharm编辑器/永久激活/翻译插件python 零基础视频教程Python 界面开发实战教程Python 爬虫实战教程Python 数据分析实战教程python 游戏开发实战教程Python 电子书100本。

m0_60635321的博客 1254

保姆级教程:用OpenCV搞定鱼眼双目相机的标定与测距(附完整C++代码)

本文详细介绍了使用OpenCV进行鱼眼双目相机标定与测距的全流程,包括环境搭建、数据采集、单目标定、双目标定、立体校正和视差计算等核心步骤。通过完整的C++代码示例和参数调优指南,帮助开发者快速实现高精度的双目测距系统,适用于机器人导航、VR全景拍摄等领域。

weixin_42573113的博客 388

RAID 0/1/5/10 性能实测:4块 SATA SSD 组阵列,顺序读写速度对比

本文通过实测对比了RAID 0/1/5/10在4块SATA SSD上的顺序读写性能,详细展示了不同RAID级别的配置方法、理论性能与实际测试数据。测试结果显示,RAID 0在顺序读写速度上表现最佳,而RAID 10则在性能与数据安全之间取得了平衡,适合数据库服务器等关键应用场景。

weixin_33462167的博客 424

Jmeter对图片验证码的处理_jemter 验证码图片插件,软件测试面试回忆录

在json提取器中通过jsonpath方法提取出code的值。识别图片验证码的字段为json格式;

2401_84264583的博客 566

Seedance2.5本地部署指南:从环境配置到生产优化的完整实践

在 AI 内容生成领域,本地部署方案正逐渐成为开发者和技术团队关注的焦点。Seedance2.5 作为一款支持图像和视频生成的 AI 工具,其完全离线运行的能力解决了云端服务在数据隐私、使用成本和访问稳定性方面的痛点。对于需要处理敏感内容、频繁生成素材或希望完全掌控生成流程的技术人员来说,掌握本地部署方法具有实际价值。 本文将以 Seedance2.5 的本地部署为例,详细介绍从环境准备、依赖配置到运行验证的完整流程,同时深入分析关键参数配置、常见问题排查方法以及生产环境下的优化建议。通过实际部署过程,理解

weixin_33139275的博客 731

最新20行 Python 代码实现验证码识别

🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

2401_84584583的博客 836

Unity 数字孪生笔记1 工具介绍

前言 工欲善其事必先利其器 流程思考 数字孪生本质上一种基于实际物理数据的可视化方案,通过对接实际数据,在三维界面中展示孪生结果。 那么这个流程就很简单了。 整个流程分为三块:数据来源-》数据分析-》数据展示 输入数据 首先我们需要考虑我们能拿到什么。第一,实际物体的三维数据从哪里来,第二,实际数据怎么获取到。 模型数据 工业上常常会用到CAD模型,CAD模型具有精确、统一的特点,但是CAD不是三角面片,我们不能直接导出到Unity中,而且导入之后有很多不合理的地方,例如面片杂乱、面数过高等问题。针对这个

Thissky的专栏 1万+

Alibaba Java Coding Guidelines,以后我的Java代码规范,就靠它了

前言 对于Java代码规范,业界有统一的标准,不少公司对此都有一定的要求。但是即便如此,庞大的Java使用者由于经验很水平的限制,未必有规范编码的意识,而且即便经验丰富的老Java 程序员也无法做到时刻将规范牢记于心。所以对于代码规范扫描工具,一经问世就广受青睐,阿里巴巴出品的Alibaba Java Coding Guidelines(阿里巴巴Java代码规约扫描,以下简称为AJCG)插件便是其...

java梦工厂 859

厉害了,用 Java 也能实现图片识别!

点击上方 "编程技术圈"关注,星标或置顶一起成长后台回复“大礼包”有惊喜礼包!每日英文When a person cannot answer directly to u...

程序员小乐 2513

在 SAP 里玩转 FTP:标准程序 RSFTP00x 全景解析与落地实践

摘要:SAP系统通过封装的标准FTP程序(RSFTP001-008)提供便捷的文件传输能力,适用于各类集成场景。关键点包括:1)依赖SAPFTP可执行程序和RFC目的地;2)使用RSFTP005进行前置检查并生成RFC配置;3)标准报表各司其职,如RSFTP002用于命令测试、RSFTP007/008提供参考实现;4)开发时组合FTP_CONNECT/COMMAND/DISCONNECT等函数模块。特别注意前台(SAPFTP)与后台(SAPFTPA)的环境差异,这是常见故障点。该方案通过标准化工具链显著降低

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 210
下一篇: 【成长笔记】Linear Regression(线性回归)
portfloat
博客等级 码龄10年 16粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值