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 相关文章推荐
python实现将汉字转换成汉语拼音的库
May 05 Python
Python实现批量修改文件名实例
Jul 08 Python
在Python的Django框架中调用方法和处理无效变量
Jul 15 Python
python:socket传输大文件示例
Jan 18 Python
详解使用 pyenv 管理多个版本 python 环境
Oct 19 Python
Django 查询数据库并返回页面的例子
Aug 12 Python
Python3使用PySynth制作音乐的方法
Sep 09 Python
python处理document文档保留原样式
Sep 23 Python
将tensorflow模型打包成PB文件及PB文件读取方式
Jan 23 Python
python函数定义和调用过程详解
Feb 09 Python
Python如何用wx模块创建文本编辑器
Jun 07 Python
Python实现弹球小游戏
Aug 01 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 MYSQL中插入当前时间
2008/04/06 PHP
解析ajax事件的调用顺序
2013/06/17 PHP
从零开始学YII2框架(六)高级应用程序模板
2014/08/20 PHP
php+ajax实现文章自动保存的方法
2014/12/30 PHP
php使用str_replace替换多维数组的实现方法分析
2017/06/15 PHP
利用onresize使得div可以随着屏幕大小而自适应的代码
2010/01/15 Javascript
jquery乱码与contentType属性设置问题解决方案
2013/01/07 Javascript
jQuery判断iframe中元素是否存在的方法
2013/05/11 Javascript
jquery监听div内容的变化具体实现思路
2013/11/04 Javascript
location.href用法总结(最主要的)
2013/12/27 Javascript
javascript制作网页图片上实现下雨效果
2015/02/26 Javascript
把Node.js程序加入服务实现随机启动
2015/06/25 Javascript
javascript实现3D变换的立体圆圈实例
2015/08/06 Javascript
使用CamanJS在Web页面上处理图像的技巧
2015/08/18 Javascript
直接拿来用的15个jQuery代码片段
2015/09/23 Javascript
整理Javascript基础入门学习笔记
2015/11/29 Javascript
js中的关联数组与普通数组详解
2016/07/27 Javascript
BootStrap Validator对于隐藏域验证和程序赋值即时验证的问题浅析
2016/12/01 Javascript
AngularJS实现页面定时刷新
2017/03/14 Javascript
详解VueJS 数据驱动和依赖追踪分析
2017/07/26 Javascript
BootStrap入门学习第一篇
2017/08/28 Javascript
ES6中定义类和对象的方法示例
2019/07/31 Javascript
jQuery操作元素追加内容示例
2020/01/10 jQuery
小程序实现可拖动的悬浮按钮
2020/09/07 Javascript
如何在面试中手写出javascript节流和防抖函数
2020/10/22 Javascript
python编写暴力破解FTP密码小工具
2014/11/19 Python
python3+PyQt5实现柱状图
2018/04/24 Python
CentOS6.9 Python环境配置(python2.7、pip、virtualenv)
2019/05/06 Python
Python谱减法语音降噪实例
2019/12/18 Python
appium+python adb常用命令分享
2020/03/06 Python
暖通工程师岗位职责
2014/06/12 职场文书
2014坚持党风廉政建设思想汇报
2014/09/18 职场文书
助学金感谢信
2015/01/20 职场文书
2015年监理个人工作总结
2015/05/23 职场文书
十一月早安语录:把心放轻,人生就是一朵自在的云
2019/11/04 职场文书
Alexa停服!网站排名将何去何从?目前还没有替代品。
2022/04/15 杂记