Python3实现的简单验证码识别功能示例

yipeiwu_com6年前Python基础

本文实例讲述了Python3实现的简单验证码识别功能。分享给大家供大家参考,具体如下:

这次的需求是自动登录某机构网站, 其验证码很具特色, 很适合做验证码识别入门demo, 先贴主要代码, 其中图片对比使用了编辑距离算法, 脚本使用了pillow库

from PIL import Image
import requests
import re
splitter = re.compile(r'\d{30}') # 分割二值化后的图片
# distance('11110000', '00000000')
# 比较两个字符串有多少位不同, 返回不同的位数
def distance(string1, string2):
  d_str1 = len(string1)
  d_str2 = len(string2)
  d_arr = [[0] * d_str2 for i in range(d_str1)]
  for i in range(d_str1):
    for j in range(d_str2):
      if string1[i] == string2[j]:
        if i == 0 and j == 0:
          d_arr[i][j] = 0
        elif i != 0 and j == 0:
          d_arr[i][j] = d_arr[i - 1][j]
        elif i == 0 and j != 0:
          d_arr[i][j] = d_arr[i][j - 1]
        else:
          d_arr[i][j] = d_arr[i - 1][j - 1]
      else:
        if i == 0 and j == 0:
          d_arr[i][j] = 1
        elif i != 0 and j == 0:
          d_arr[i][j] = d_arr[i - 1][j] + 1
        elif i == 0 and j != 0:
          d_arr[i][j] = d_arr[i][j - 1] + 1
        else:
          d_arr[i][j] = min(d_arr[i][j - 1], d_arr[i - 1][j], d_arr[i - 1][j - 1]) + 1
  current = max(d_arr[d_str1 - 1][d_str2 - 1], abs(d_str2 - d_str1))
  # print("Levenshtein Distance is",current)
  # print(current)
  return current
# 去除字符串里面连续的1
def no_one(string):
  n_arr = splitter.findall(string)
  n_arr = filter(lambda each_str: each_str != '111111111111111111111111111111', n_arr)
  n_result = ''
  for n_each in n_arr:
    n_result += str(n_each)
  return n_result
opener = requests.session()
res = opener.get('http://60.211.254.236:8402/Ajax/ValidCodeImg.ashx').content
with open('verify.gif', 'wb') as v:
  v.write(res)
img = Image.open('verify.gif')
img = img.convert('L')
size = img.size
# img = img.point(table, '1')
img_arr = img.load()
# for x in range(size[0]):
#   for y in range(size[1]):
#     if img_arr[x, y] > 210:
#       img_arr[x, y] = 1
#     else:
#       img_arr[x, y] = 0
# img.save('after.gif')
inc = 0
str1 = ''
str2 = ''
str3 = ''
cur_str = ''
for x in range(size[0]):
  for y in range(size[1]):
    if img_arr[x, y] > 210:
      cur_str += '1'
    else:
      cur_str += '0'
    # print(img_arr[i, j], end='')
    # cur_str += str(img_arr[x, y])
  inc += 1
  # if inc % 18 == 0:
  #   print('\n----')
  # else:
  #   print('')
  if inc == 18:
    str1 = cur_str
    cur_str = ''
  elif inc == 36:
    str2 = cur_str
    cur_str = ''
  elif inc == 54:
    str3 = cur_str
    cur_str = ''
str1 = str1[:-60]
str2 = str2[:-60]
str3 = str3[:-60]
str1 = no_one(str1)
str2 = no_one(str2)
str3 = no_one(str3)
str1 = str1.strip('1')
str2 = str2.strip('1')
str3 = str3.strip('1')
# print(str1)
# print(str3)
with open('./dict/plus') as plus:
  with open('./dict/minus') as minus:
    p = plus.read()
    m = minus.read()
    is_add = 1 if distance(p, str2) < distance(m, str2) else 0
arr1 = []
arr3 = []
for each in range(1, 10):
  with open('./dict/{}'.format(each)) as f:
    ff = f.read()
    arr1.append([each, distance(ff, str1)])
    arr3.append([each, distance(ff, str3)])
arr1 = sorted(arr1, key=lambda item: item[1])
arr3 = sorted(arr3, key=lambda item: item[1])
result = arr1[0][0] + arr3[0][0] if is_add else arr1[0][0] - arr3[0][0]
print(result)
# login_url = 'http://60.211.254.236:8402/Ajax/Login.ashx?Method=G3_Login'
# login_data = {
#   'loginname': usn,
#   'password': pwd,
#   'validcode': result,
#
# }
# opener.get(login_url, login_data)

字库已经部署到GitHub地址:https://github.com/hldh214/validCode/

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python图片操作技巧总结》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总

希望本文所述对大家Python程序设计有所帮助。

相关文章

在python中实现对list求和及求积

如下所示: # the basic way s = 0 for x in range(10): s += x # the right way s = sum(range(10))...

对python while循环和双重循环的实例详解

废话不多说,直接上代码吧! #python中,while语句用于循环执行程序,即在某个条件下,循环执行某段程序,以处理需要重复处理的相同任务。 #while是“当型”循环结构。 i=...

Python 中Pickle库的使用详解

Python 中Pickle库的使用详解

在“通过简单示例来理解什么是机器学习”这篇文章里提到了pickle库的使用,本文来做进一步的阐述。 那么为什么需要序列化和反序列化这一操作呢?   1.便于存储。序列化过程将文本信息转变...

Python将字符串常量转化为变量方法总结

前几天,我们Python猫交流学习群 里的 M 同学提了个问题。这个问题挺有意思,经初次讨论,我们认为它无解。 然而,我认为它很有价值,应该继续思考怎么解决,所以就在私密的知识星球上记录...

浅谈Python接口对json串的处理方法

最近学习Python接口测试,对于接口测试完全小白。大概一周的学习成果进行总结。 1.接口测试: 目前涉及到的只是对简单单一的接口进行参数传递,得到返回自。 2.关于各种概念: 2.1...