强智科技验证码识别

前言

由于近期在写一个教务系统的爬虫程序,但是网站的验证码让人很头疼,所以笔者临时找了一些资料学习了一下,本人python用的很少,而且在机器学习这块也是新手,从来没有接触过,所以写的不好还请指点出来。

环境
 python3.6PILsklearn
准备

使用一个简单的脚本下载1000张验证码,然后做好标记

 import requestsurl = "http://****/verifycode.servlet"for i in range(1000):filename = "./code/"+str(i)+".png"response = requests.get(url)with open(filename , "wb") as f:f.write(response.content)

图像处理

实例图片

1.二值化,这里我们进行手动利用一个阈值进行二值化,处理完成以后的图片如下

2.降噪,思路是,当一个点他为黑色时,周围8(这个数字改小一点还可以完成线去除干扰线的功能,我这里就是使用这种方式将干扰点和干扰线去除的)个点都是白色则认为这是一个噪点

我们发现还是有一个点没有去除,没有关系,下面我们做字符分割的时候还是会进行一次降噪

3.字符分割,思路是找出每个数字的边缘坐标,如果上下边缘相差太小的话则认为这里为噪点,直接去除

图片转换为数据

上面已经分割好了,我们现在需要将图片转换成数据,方便我们下面传入机器学习,我用的方式是遍历分割好的方形区域,黑色为1,白色为0,拼接成一个类似于“0011010100000101111111111”的字符串,然后将字符串转换成int型数值

最后生成的数据是下面这种样子
图片数据:[“61256415613215646512” , “61256415613215646512” , “61256415613215646512” , “61256415613215646512”]
结果数据:[‘1’ , ‘j’ , ‘k’ , ‘d’]

训练模型

我是用的是knn分类算法

代码

1.图像处理类

 from PIL import Image , ImageDraw
import cv2'''图片处理类
'''
class ImageHandler():threshold = 130 #二值化处理阈值im = None        #保存当前类所处理的图片spliter = []data = []labels = []def __init__(self , filename):self.filename = filename self.data = []self.labels = []self.spliter = []self.im = None'''图片文件读取'''def readFile(self):self.im = Image.open(self.filename)'''图片二值化'''#def toBinary_img(self , im):#    im = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#  th1 = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 1)#    return th1'''手动将图片二值化顺便去掉边框'''def toBinary_data(self):self.readFile()im = self.imim = im.convert('L')pixdata = im.load()width , height = im.sizefor j in range(height):for i in range(width):if(i == 0 or i == width-1 or j == 0 or j == height-1):pixdata[i , j] = 255continueif(pixdata[i , j] < self.threshold):pixdata[i , j] = 0else:pixdata[i , j] = 255self.im = im'''降噪(点线降噪)'''def dot_noise(self):im = self.imw , h = im.sizepixdata = im.load()#从左至右降噪for y in range(h):for x in range(w):if(pixdata[x , y] == 0):sum = 0 #四周总共有多少个白点if(pixdata[x-1 , y] == 255):sum+=1if(pixdata[x+1 , y] == 255):sum+=1if(pixdata[x , y+1] == 255):sum+=1if(pixdata[x , y-1] == 255):sum+=1if(pixdata[x-1 , y-1] == 255):sum+=1if(pixdata[x-1 , y+1] == 255):sum+=1if(pixdata[x+1 , y-1] == 255):sum+=1if(pixdata[x+1 , y+1] == 255):sum+=1if(sum >= 7): #这里为7的时候图片处理这完整,但是当准确率不及为5的时候,所以真正应用的时候建议将它改成5,下面那个也一样pixdata[x , y] = 255'''#从右至左降噪for y in range(h):for x in range(w-1 , -1 , -1):if(pixdata[x , y] == 0):sum = 0 #四周总共有多少个白点if(pixdata[x-1 , y] == 255):sum+=1if(pixdata[x+1 , y] == 255):sum+=1if(pixdata[x , y+1] == 255):sum+=1if(pixdata[x , y-1] == 255):sum+=1if(sum >= 3):pixdata[x , y] = 255'''#从下至上降噪for y in range(h-1 , -1 , -1):for x in range(w-1 , -1 , -1):if(pixdata[x , y] == 0):sum = 0 #四周总共有多少个白点if(pixdata[x-1 , y] == 255):sum+=1if(pixdata[x+1 , y] == 255):sum+=1if(pixdata[x , y+1] == 255):sum+=1if(pixdata[x , y-1] == 255):sum+=1if(pixdata[x-1 , y-1] == 255):sum+=1if(pixdata[x-1 , y+1] == 255):sum+=1if(pixdata[x+1 , y-1] == 255):sum+=1if(pixdata[x+1 , y+1] == 255):sum+=1if(sum >= 7):pixdata[x , y] = 255self.im = im'''切割'''def cut_img(self):im = self.imw , h = im.sizepixdata = im.load()#1.找出切割点spliter_y = []spliter_x = []flag = False  #表示当前遍历的全部为白色,当遇到黑色时就会变成True#1.1找纵向切割点for x in range(w):column = False #当前行全是白色则为False , 否则为Truefor y in range(h):if(pixdata[x , y] == 0):column = Trueif(flag == False):flag = Truespliter_x.append(x - 1)if(flag == True and column == False):spliter_x.append(x)if(column == False):flag = False#print(self.filename)#判断是否有字符粘连,如果有就进行切割for i in range(0 , len(spliter_x) , 2):#两个粘连的问题if(spliter_x[i+1] - spliter_x[i] > 21 and spliter_x[i+1] - spliter_x[i] < 43):x = spliter_x[i]y = spliter_x[i+1]spliter_x[i+1] = x+19spliter_x.insert(i+2 , y)spliter_x.insert(i+2 , x+19)if(i == 0):if(spliter_x[i+5] - spliter_x[i+4] > 21):x = spliter_x[i+4]y = spliter_x[i+5]spliter_x[i+5] = x+19spliter_x.insert(i+6 , y)spliter_x.insert(i+6 , x+19)break #三个粘连的问题elif(spliter_x[i+1] - spliter_x[i] >= 43):x = spliter_x[i]y = spliter_x[i+1]spliter_x[i+1] = x+19spliter_x.insert(i+2 , y)spliter_x.insert(i+2 , x+37)spliter_x.insert(i+2 , x+37)spliter_x.insert(i+2 , x+19)break ;#print(spliter_x)    #2.2找横向切割点for i in range(0 , len(spliter_x) , 2):#1.1.1先从上到下找到顶部临界点flag = Falsefor y in range(h):for x in range(spliter_x[i] , spliter_x[i+1]):if(pixdata[x , y] == 0):if(flag == False):flag = Truespliter_y.append(y)break ;if(flag == True):break#1.1.2从下至上找到底部临界点flag = Falsefor y in range(h-1 , -1 , -1):for x in range(spliter_x[i] , spliter_x[i+1]):if(pixdata[x , y] == 0):if(flag == False):flag = Truespliter_y.append(y+1)breakif(flag == True):break#再次降噪temp_arr_x = []temp_arr_y = []for i in range(0 , len(spliter_y) , 2):#print(str(spliter_y[i+1]) +"\t"+ str(spliter_y[i]))if(spliter_y[i+1] - spliter_y[i] <= 4):for x in range(spliter_x[i] , spliter_x[i+1]):for y in range(spliter_y[i] , spliter_y[i+1]):pixdata[x , y] = 255spliter_x[i] = 0spliter_x[i+1] = 0spliter_y[i] = 0spliter_y[i+1] = 0else:temp_arr_x.append(spliter_x[i])temp_arr_x.append(spliter_x[i+1])temp_arr_y.append(spliter_y[i])temp_arr_y.append(spliter_y[i+1])spliter_x = temp_arr_xspliter_y = temp_arr_y#将分割点进行存储result = [[] , [] , [] , []]#print(len(spliter_x))if(len(spliter_x) == 8):for i in range(len(result)):result[i].append(spliter_x[i*2])result[i].append(spliter_y[i*2])result[i].append(spliter_x[i*2+1])result[i].append(spliter_y[i*2+1])else:return Falseself.spliter = resultdef test(self):'''测试切割后的结果'''for index , i in enumerate(self.spliter):box = tuple(i)region = self.im.crop(box)w , h = region.sizew = w - 1h = h - 1draw = ImageDraw.Draw(region)draw.line((0 , 0 , w , 0) , fill=160)draw.line((0 , 0 , 0 , h) , fill=160)draw.line((w , 0 , w , h) , fill=160)draw.line((0 , h , w , h) , fill=160)del drawself.im.paste(region, box)#region.save(str(index)+".png" , "PNG")'''将分割好的图片转换成机器学习数据'''def img_2_train_data(self):f = self.filename.replace(".png" , "")[-4:]for index , i in enumerate(self.spliter):box = tuple(i)region = self.im.crop(box)w , h = region.sizepixdata = region.load()d = "0b"for y in range(h):for x in range(w):if(pixdata[x , y] == 0):d+='1'else:d+='0'self.data.append(int(d , 2))self.labels.append(f[index])

2.训练代码

from numpy import *
import numpy as np
from sklearn import neighbors
import os
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.externals import joblib
from ImageHandler import ImageHandler
from PIL import Imageimg_dir = "./code"
files = os.listdir(img_dir)data = []
result = []for i in range(len(files)):path = img_dir+"/"+files[i]image = ImageHandler(path)image.toBinary_data()image.dot_noise()image.cut_img()image.img_2_train_data()data = np.append(data , image.data)result = np.append(result , image.labels)del imageprint("数据准备完毕")x = data.reshape(-1 , 1)
y = result.reshape(-1 , 1)
x = np.array(x)
y = np.array(y)# 拆分训练数据与测试数据
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1)
# 训练KNN分类器
clf = neighbors.KNeighborsClassifier()
clf.fit(x, y)print("训练完成")# 保存分类器模型
joblib.dump(clf, './knn/knn.pkl')print("结束")print("检验准确率")# # 测试结果打印
pre_y_train = clf.predict(x_train)
pre_y_test = clf.predict(x_test)
class_name1 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9' , 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' , 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't' , 'u', 'v', 'w', 'x']
class_name2 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9' , 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' , 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't' , 'u', 'v', 'w', 'x']
print (classification_report(y_train, pre_y_train, target_names=class_name1))
print (classification_report(y_test, pre_y_test, target_names=class_name2))
以上就是我这次破解验证码的全部过程,如果大佬觉得有更好的方式欢迎留言讨论,加我qq也行:1730145232

强智科技教务系统验证码识别相关推荐

  1. python登录教务系统_强智科技教务系统python爬虫模拟登录分析(湖南)

    强智科技教务系统python爬虫模拟登录分析(湖南) 本文章仅用作于学习 前提:最近期末到来,想第一时间看到新出成绩的,于是就有了爬取学校教务系统自己的成绩并通过Qmsg酱推送到自己QQ上的想法,目前 ...

  2. python爬虫获取强智科技教务系统学科成绩(模拟登录+成绩获取)

    python爬取强智科技教务系统,以江苏科技大学为例:本人开发的系统作为参考:https://www.wjn1996.cn/estudy/tools/educationLogin.jsp?school ...

  3. python实现强智科技教务系统抢课(两种方法)

    前言 又到了选课的时间,又一次被教务系统的预选给安排了,硬是一门都没选中.于是想实现有没有自动捡课的方法.就整体分为两种方法,一种是获取get请求然后由python多线程提交去选课,一种是利用自动化测 ...

  4. 强智科技教务系统学科成绩c语言,湖南强智科技教务系统python模拟登录并爬取成绩(财院)...

    其实之前有写过一篇帖子了 在之前使用教务系统的过程中,偶然一次发现登上教务系统后再退出来的后的登录网址竟然不需要验证码,想着之前有写过教务系统的爬虫模拟登录,没验证码的岂不是更好干(之前那次折腾了好久 ...

  5. 计算机算法基础_强智科技继续冠名第十六届“强智杯”湖南省大学生计算机程序设计竞赛...

    2020年10月17-18日,第十六届"强智杯"湖南省大学生计算机程序设计竞赛在长沙理工大学成功举办,本次竞赛由省教育厅主办.省高教学会计算机教育专业委员会协办.长沙理工大学承办, ...

  6. 正方教务系统验证码自动识别(非打码平台)

    本人用的是网上的Java版本,经过本人的改良只剩下验证码识别. 详细说明请看  http://www.unique-liu.com/181.html ImagePreProcess.srcPath = ...

  7. SZTU深圳技术大学教务系统小爱课程表导入——强智科技13369

    作为个人来讲非常值得纪念的,具有一定流传度的,较为正规的小项目--小爱课程表导入,于2020/9/9正式完成.审核通过时间暂未明确,测试已经完美. 2020/9/16修复已知的BUG 2020/9/2 ...

  8. 获取广西财经学院教务系统验证码Demo(hls编辑)

    2019独角兽企业重金招聘Python工程师标准>>> 通过抓包获取到该网站的验证码请求地址,使用HttpClient的get方法获取该验证码 java文件: package com ...

  9. 强智科技教务处模拟登录

    通过对教务处登录进行抓包分析,发现登录教务处只需要两个操作 1 将username和password两个的值post到http://202.114.242.21/whkjdx/Logon.do?met ...

最新文章

  1. hadoop学习之一
  2. 三种复方门冬维甘滴眼液的抗菌能力比较
  3. Page.FindControl方法找不到指定控件的原因
  4. 【华为云技术分享】基于ModelArts AI市场算法MobileNet_v2实现花卉分类,支持CPU、GPU、Ascend推理
  5. 软件设计原则(三) 依赖倒置原则
  6. excel题库做成刷题得html,实例教你制作简易的Excel出题库,送给在一直忙碌的你!...
  7. skype国际版android,Skype国际版
  8. 4G标准LTE FDD与LTE TDD的不同
  9. 基于MATLAB语音分析处理系统
  10. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、编写自定义三线表结构(将因子变量细粒度化重新构建三线图)
  11. 微信40125错误的坑
  12. 哪些人适合转行学习IT技术
  13. java时间显示时区_Java 时间、日期与时区的关系
  14. 奇异值分解(SVD)线性变换和几何意义
  15. mac的 tr命令_tr命令 - Holy_Shit - 博客园
  16. 数据库---[复习2]---数据查询---设有一个SPJ数据库,包括S、P、J及SPJ4个关系模式··· ···
  17. 【LeetCode】954. Array of Doubled Pairs 解题报告(Python)
  18. 快讯 | 公链专场,四位大咖分享了些什么(附PPT)
  19. 上周热点回顾(12.5-12.11)
  20. Mark-sweep GC

热门文章

  1. email正则表达式 验证邮箱格式
  2. HTML5之简单小画板
  3. 离散数学——全序/偏序关系及应用
  4. 解决Ctfmon.exe恶梦--禁止文字服务 OFFICE2000/XP
  5. python locals()用法_python – Django使用locals()[复制]
  6. NSString的stringWithFormat用法
  7. python基础小知识
  8. 深圳友坚推出最新三星ARM Cortex-A8内核的S5PV210开发板,1GHZ主频处理器强悍登场
  9. 鼠来宝3[Alvin and the Chipmunks:Chipwrecked]
  10. 天涯若比邻的上一句是什么,这首诗作者是谁、表达的是什么意思?