python识别验证码图片实例详解


Posted in Python onFebruary 17, 2020

在编写自动化测试用例的时候,每次登录都需要输入验证码,后来想把让python自己识别图片里的验证码,不需要自己手动登陆,所以查了一下识别功能怎么实现,做一下笔记。

首选导入一些用到的库,re、Image、pytesseract、selenium、time

import re # 用于正则
from PIL import Image # 用于打开图片和对图片处理
import pytesseract # 用于图片转文字
from selenium import webdriver # 用于打开网站
import time # 代码运行停顿

首先需要获取验证码图片,才能进一步识别。

创建类,定义webdriver和find_element_by_selector方法,用来打开网页和定位验证码图片的元素

class VerificationCode:
 def __init__(self):
  self.driver = webdriver.Firefox()
  self.find_element = self.driver.find_element_by_css_selector

然后打开浏览器截取验证码图片

def get_pictures(self):
  self.driver.get('http://123.255.123.3') # 打开登陆页面
  self.driver.save_screenshot('pictures.png') # 全屏截图
  page_snap_obj = Image.open('pictures.png')
  img = self.find_element('#pic') # 验证码元素位置
  time.sleep(1)
  location = img.location
  size = img.size # 获取验证码的大小参数
  left = location['x']
  top = location['y']
  right = left + size['width']
  bottom = top + size['height']
  image_obj = page_snap_obj.crop((left, top, right, bottom)) # 按照验证码的长宽,切割验证码
  image_obj.show() # 打开切割后的完整验证码
  self.driver.close() # 处理完验证码后关闭浏览器
  return image_obj

未处理前的验证码图片如下:

python识别验证码图片实例详解

未处理的验证码图片,对于python来说识别率较低,仔细看可以发现图片里有很对五颜六色扰乱识别的点,非常影响识别率。

下面对获取的验证码进行处理。

首先用convert把图片转成黑白色。设置threshold阈值,超过阈值的为黑色

def processing_image(self):
  image_obj = self.get_pictures() # 获取验证码
  img = image_obj.convert("L") # 转灰度
  pixdata = img.load()
  w, h = img.size
  threshold = 160 # 该阈值不适合所有验证码,具体阈值请根据验证码情况设置
  # 遍历所有像素,大于阈值的为黑色
  for y in range(h):
   for x in range(w):
    if pixdata[x, y] < threshold:
     pixdata[x, y] = 0
    else:
     pixdata[x, y] = 255
  return img

经过灰度处理后的图片

python识别验证码图片实例详解

然后删除一些扰乱识别的像素点。

def delete_spot(self):
  images = self.processing_image()
  data = images.getdata()
  w, h = images.size
  black_point = 0
  for x in range(1, w - 1):
   for y in range(1, h - 1):
    mid_pixel = data[w * y + x] # 中央像素点像素值
    if mid_pixel < 50: # 找出上下左右四个方向像素点像素值
     top_pixel = data[w * (y - 1) + x]
     left_pixel = data[w * y + (x - 1)]
     down_pixel = data[w * (y + 1) + x]
     right_pixel = data[w * y + (x + 1)]
     # 判断上下左右的黑色像素点总个数
     if top_pixel < 10:
      black_point += 1
     if left_pixel < 10:
      black_point += 1
     if down_pixel < 10:
      black_point += 1
     if right_pixel < 10:
      black_point += 1
     if black_point < 1:
      images.putpixel((x, y), 255)
     black_point = 0
  # images.show()
  return images

经过去除噪点处理后的图片

python识别验证码图片实例详解

最后把处理后的图片转成文字。

先设置pytesseract的路径,因为默认路径是错的,然后转换图片为文字,由于个别图片中识别会出现处理遗漏,会被识别成空格或则点或则分号什么的,所以增加了一个去除验证码中特殊字符的处理。

def image_str(self):
  image = self.delete_spot()
  pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe" # 设置pyteseract路径
  result = pytesseract.image_to_string(image) # 图片转文字
  resultj = re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])", "", result) # 去除识别出来的特殊字符
  result_four = resultj[0:4] # 只获取前4个字符
  # print(resultj) # 打印识别的验证码
  return result_four

完整代码如下:

import re # 用于正则
from PIL import Image # 用于打开图片和对图片处理
import pytesseract # 用于图片转文字
from selenium import webdriver # 用于打开网站
import time # 代码运行停顿
 
 
class VerificationCode:
 def __init__(self):
  self.driver = webdriver.Firefox()
  self.find_element = self.driver.find_element_by_css_selector
 
 def get_pictures(self):
  self.driver.get('http://123.255.123.3') # 打开登陆页面
  self.driver.save_screenshot('pictures.png') # 全屏截图
  page_snap_obj = Image.open('pictures.png')
  img = self.find_element('#pic') # 验证码元素位置
  time.sleep(1)
  location = img.location
  size = img.size # 获取验证码的大小参数
  left = location['x']
  top = location['y']
  right = left + size['width']
  bottom = top + size['height']
  image_obj = page_snap_obj.crop((left, top, right, bottom)) # 按照验证码的长宽,切割验证码
  image_obj.show() # 打开切割后的完整验证码
  self.driver.close() # 处理完验证码后关闭浏览器
  return image_obj
 
 def processing_image(self):
  image_obj = self.get_pictures() # 获取验证码
  img = image_obj.convert("L") # 转灰度
  pixdata = img.load()
  w, h = img.size
  threshold = 160
  # 遍历所有像素,大于阈值的为黑色
  for y in range(h):
   for x in range(w):
    if pixdata[x, y] < threshold:
     pixdata[x, y] = 0
    else:
     pixdata[x, y] = 255
  return img
 
 def delete_spot(self):
  images = self.processing_image()
  data = images.getdata()
  w, h = images.size
  black_point = 0
  for x in range(1, w - 1):
   for y in range(1, h - 1):
    mid_pixel = data[w * y + x] # 中央像素点像素值
    if mid_pixel < 50: # 找出上下左右四个方向像素点像素值
     top_pixel = data[w * (y - 1) + x]
     left_pixel = data[w * y + (x - 1)]
     down_pixel = data[w * (y + 1) + x]
     right_pixel = data[w * y + (x + 1)]
     # 判断上下左右的黑色像素点总个数
     if top_pixel < 10:
      black_point += 1
     if left_pixel < 10:
      black_point += 1
     if down_pixel < 10:
      black_point += 1
     if right_pixel < 10:
      black_point += 1
     if black_point < 1:
      images.putpixel((x, y), 255)
     black_point = 0
  # images.show()
  return images
 
 def image_str(self):
  image = self.delete_spot()
  pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe" # 设置pyteseract路径
  result = pytesseract.image_to_string(image) # 图片转文字
  resultj = re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])", "", result) # 去除识别出来的特殊字符
  result_four = resultj[0:4] # 只获取前4个字符
  # print(resultj) # 打印识别的验证码
  return result_four
 
 
 
if __name__ == '__main__':
 a = VerificationCode()
 a.image_str()

更多关于python识别验证码图片方法请查看下面的相关链接

Python 相关文章推荐
Pyramid添加Middleware的方法实例
Nov 27 Python
Python 编码处理-str与Unicode的区别
Sep 06 Python
关于Python面向对象编程的知识点总结
Feb 14 Python
python Flask实现restful api service
Dec 04 Python
Django中针对基于类的视图添加csrf_exempt实例代码
Feb 11 Python
基于python 二维数组及画图的实例详解
Apr 03 Python
IntelliJ IDEA安装运行python插件方法
Dec 10 Python
PyQt5多线程刷新界面防假死示例
Dec 13 Python
安装多个版本的TensorFlow的方法步骤
Apr 21 Python
python 6行代码制作月历生成器
Sep 18 Python
Python通过format函数格式化显示值
Oct 17 Python
Python爬虫设置Cookie解决网站拦截并爬取蚂蚁短租的问题
Feb 22 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
Feb 17 #Python
Matplotlib使用字符串代替变量绘制散点图的方法
Feb 17 #Python
关于tf.TFRecordReader()函数的用法解析
Feb 17 #Python
将数据集制作成VOC数据集格式的实例
Feb 17 #Python
将labelme格式数据转化为标准的coco数据集格式方式
Feb 17 #Python
开启Django博客的RSS功能的实现方法
Feb 17 #Python
Python3打包exe代码2种方法实例解析
Feb 17 #Python
You might like
php下实现一个阿拉伯数字转中文数字的函数
2008/07/10 PHP
PHP OPP机制和模式简介(抽象类、接口和契约式编程)
2014/06/09 PHP
图文详解PHP环境搭建教程
2016/07/16 PHP
php实现数据库的增删改查
2017/02/26 PHP
PHP实现正则表达式分组捕获操作示例
2018/02/03 PHP
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
2010/06/18 Javascript
5个javascript的数字格式化函数分享
2011/12/07 Javascript
js判断样式className同时增加class或删除class
2013/01/30 Javascript
JQuery中对Select的option项的添加、删除、取值
2013/08/25 Javascript
javascript中的括号()用法小结
2014/04/14 Javascript
使用纯JS代码判断字符串中有多少汉字的实现方法(超简单实用)
2016/11/12 Javascript
原生js实现对Ajax的封装(仿jquery)
2017/01/22 Javascript
CSS3+JavaScript实现翻页幻灯片效果
2017/06/28 Javascript
easyui-datagrid开发实践(总结)
2017/08/02 Javascript
vue-openlayers实现地图坐标弹框效果
2020/09/24 Javascript
[01:07:22]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG加赛
2014/05/26 DOTA
Python下的常用下载安装工具pip的安装方法
2015/11/13 Python
windows10系统中安装python3.x+scrapy教程
2016/11/08 Python
Matplotlib中文乱码的3种解决方案
2018/11/15 Python
Python使用scipy模块实现一维卷积运算示例
2019/09/05 Python
opencv3/C++实现视频背景去除建模(BSM)
2019/12/11 Python
python 使用elasticsearch 实现翻页的三种方式
2020/07/31 Python
Windows环境下Python3.6.8 importError: DLLload failed:找不到指定的模块
2020/11/01 Python
Pandas中两个dataframe的交集和差集的示例代码
2020/12/13 Python
python基于pexpect库自动获取日志信息
2021/02/01 Python
python pyg2plot的原理知识点总结
2021/02/28 Python
Boutique 1美国:阿联酋奢侈时尚零售商
2017/10/16 全球购物
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
初婚初育证明
2014/01/14 职场文书
爱情检讨书大全
2014/01/21 职场文书
乡镇总工会学雷锋活动总结
2014/03/01 职场文书
三月学雷锋月活动总结
2014/04/28 职场文书
和睦家庭事迹
2014/05/14 职场文书
元旦联欢会策划方案
2014/06/11 职场文书
利用python Pandas实现批量拆分Excel与合并Excel
2021/05/23 Python
小喇叭开始广播了! 四十多年前珍贵老照片
2022/05/09 无线电