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获取当前日期和时间的方法
Apr 30 Python
在Python中操作字符串之replace()方法的使用
May 19 Python
python从入门到精通(DAY 2)
Dec 20 Python
Python基于二分查找实现求整数平方根的方法
May 12 Python
Python实现的rsa加密算法详解
Jan 24 Python
Python微信公众号开发平台
Jan 25 Python
python跳过第一行快速读取文件内容的实例
Jul 12 Python
Python通过socketserver处理多个链接
Mar 18 Python
python 6.7 编写printTable()函数表格打印(完整代码)
Mar 25 Python
Pycharm连接远程服务器过程图解
Apr 30 Python
python3爬虫中多线程进行解锁操作实例
Nov 25 Python
使用python生成大量数据写入es数据库并查询操作(2)
Sep 23 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中ini_set和ini_get函数的用法小结
2014/02/18 PHP
php实现根据字符串生成对应数组的方法
2014/09/22 PHP
php实现数组中索引关联数据转换成json对象的方法
2015/07/08 PHP
PHP中类的自动加载的方法
2017/03/17 PHP
php脚本守护进程原理与实现方法详解
2017/07/20 PHP
JQuery 实现的页面滚动时浮动窗口控件
2009/07/10 Javascript
JavaScript的parseInt 取整使用
2011/05/09 Javascript
jQuery EasyUI API 中文文档 - ComboBox组合框
2011/10/07 Javascript
JS和jquery获取各种屏幕的宽度和高度的代码
2013/08/02 Javascript
多种方式实现JS调用后台方法进行数据交互
2013/08/20 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
Angularjs过滤器使用详解
2016/05/25 Javascript
微信小程序 form组件详解
2016/10/25 Javascript
jquery二级目录选中当前页的css样式
2016/12/08 Javascript
详解Vuejs2.0之异步跨域请求
2017/04/20 Javascript
解决微信小程序防止无法回到主页的问题
2018/09/28 Javascript
Async/Await替代Promise的6个理由
2019/06/15 Javascript
React中使用Vditor自定义图片详解
2020/12/25 Javascript
python实现获取Ip归属地等信息
2016/08/27 Python
python实现Zabbix-API监控
2018/09/17 Python
python 提取tuple类型值中json格式的key值方法
2018/12/31 Python
对python中类的继承与方法重写介绍
2019/01/20 Python
Python编程实现tail-n查看日志文件的方法
2019/07/08 Python
Django查询优化及ajax编码格式原理解析
2020/03/25 Python
解决 jupyter notebook 回车换两行问题
2020/04/15 Python
eDreams德国:南欧领先的在线旅游公司
2020/12/07 全球购物
介绍一下MYSQL常用的优化技巧
2012/10/25 面试题
Java面向对象面试题
2016/12/26 面试题
教师专业理论水平的自我评价分享
2013/11/09 职场文书
自荐书模板
2013/12/15 职场文书
乐观大学生的自我评价
2014/01/10 职场文书
二手房购房意向书范本
2014/04/01 职场文书
小学生家长寄语
2014/04/02 职场文书
开展党的群众路线教育实践活动工作总结
2014/11/05 职场文书
中班下学期个人工作总结
2015/02/12 职场文书
护士自荐信范文
2015/03/25 职场文书