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实现SMTP邮件发送功能
Jun 16 Python
关于反爬虫的一些简单总结
Dec 13 Python
Python实现的简单计算器功能详解
Aug 25 Python
在Python中使用defaultdict初始化字典以及应用方法
Oct 31 Python
使用python读取.text文件特定行的数据方法
Jan 28 Python
tensorflow 变长序列存储实例
Jan 20 Python
基于python实现地址和经纬度转换
May 19 Python
python根据字典的键来删除元素的方法
Aug 16 Python
Django haystack实现全文搜索代码示例
Nov 28 Python
浅谈盘点5种基于Python生成的个性化语音方法
Feb 05 Python
浅谈Python xlwings 读取Excel文件的正确姿势
Feb 26 Python
Python pandas读取CSV文件的注意事项(适合新手)
Jun 20 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 smarty模版引擎中的缓存应用
2009/12/11 PHP
PHP实现恶意DDOS攻击避免带宽占用问题方法
2015/05/27 PHP
php上传大文件失败的原因及应对策略
2015/10/20 PHP
前端必学之PHP语法基础
2016/01/01 PHP
PHP编程实现csv文件导入mysql数据库的方法
2017/04/29 PHP
PHP多线程模拟实现秒杀抢单
2018/02/07 PHP
javascript截取字符串(通过substring实现并支持中英文混合)
2013/06/24 Javascript
JavaScript淡入淡出渐变简单实例
2015/08/06 Javascript
jQuery zclip插件实现跨浏览器复制功能
2015/11/02 Javascript
jQuery1.9+中删除了live以后的替代方法
2016/06/17 Javascript
浅谈webpack打包生成的bundle.js文件过大的问题
2018/02/22 Javascript
详解Node.js读写中文内容文件操作
2018/10/10 Javascript
微信小程序使用scroll-view标签实现自动滑动到底部功能的实例代码
2018/11/09 Javascript
[03:42]2014DOTA2西雅图国际邀请赛 Navi战队巡礼
2014/07/07 DOTA
详解Python验证码识别
2016/01/25 Python
python编写简单爬虫资料汇总
2016/03/22 Python
Python利用itchat对微信中好友数据实现简单分析的方法
2017/11/21 Python
python2与python3共存问题的解决方法
2018/09/18 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
基于HTML5的齿轮动画特效
2016/02/29 HTML / CSS
新西兰领先的鞋类和靴子网上商城:Merchant 1948
2017/09/08 全球购物
乐天旅游香港网站:日本饭店预订
2017/11/29 全球购物
SIMON MILLER官网:洛杉矶的生活方式品牌
2020/10/19 全球购物
Java中会存在内存泄漏吗,请简单描述
2016/12/22 面试题
写好自荐信的要点
2013/11/06 职场文书
关于幼儿的自我评价
2013/12/18 职场文书
建筑人员岗位职责
2013/12/25 职场文书
研究生毕业鉴定
2014/01/29 职场文书
2014年高考决心书
2014/03/11 职场文书
2014年党员发展工作总结
2014/12/02 职场文书
西湖英语导游词
2015/02/06 职场文书
办公室主任岗位竞聘书
2015/09/15 职场文书
2016年领导干部正风肃纪心得体会
2015/10/09 职场文书
2016年“我们的节日·重阳节”主题活动总结
2016/04/01 职场文书
使用Canvas绘制一个游戏人物属性图
2022/03/25 Javascript
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
2022/05/30 NodeJs