注:这个是我当初爬学校的URP系统时写的代码,只写了一半左右。
其中涉及了,验证码图片的一些处理,当初因为时间有限,图片的二值化那里,应该是不够严谨,因为它只适用于一般字母与背景区分度比较明显的二值化,而我们学校的URP就比较坑人了,它的背景图与字母都是差不多颜色的,而我又不清楚这个颜色划分,所以进行不下去了,但是这个代码对于处理一般的验证码还是有作用的
而且,我的pycharm是安装不上 tesseract 库的,就读不出来图片里的字符串,具体原因不详,所以,整体上,以失败告终
import random
import requests
import os
import time
import bs4
from PIL import Image
import ctypes
import pytesseract
# import tesseract
import re
from bs4 import BeautifulSoup
url="http://115.24.160.162/validateCodeAction.do?random="
header={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0'}
dir="D:\\VER\\"
path=dir+"ver.png"
def getVerificationCode():#获取验证码,并写入文件
a=random.random()#生成16位随机数
print(str(a)[:-1])
try:
r=requests.get(url+str(a)[-1],headers=header,timeout=20)
r.raise_for_status()
if not os.path.exists(dir):
os.mkdir(dir)
if not os.path.exists(path):#写入文件在进行操作
with open(path,"wb") as f:
f.write(r.content)
except:
print("下载验证码失败")
def Binarization():#实现图片二值化
i=0
img=Image.open(path)
img=img.convert("RGBA")
while i < 4: # 循环次数视情况进行调整
i = i + 1
pixdata = img.load()
# 一次二值化
for y in range(img.size[1]):
for x in range(img.size[0]):
if pixdata[x, y][0] < 90: # 使RGB值中R小于90的像素点变成纯黑
pixdata[x, y] = (0, 0, 0, 255)
for y in range(img.size[1]):
for x in range(img.size[0]):
if pixdata[x, y][1] < 190: # 使RGB值中G小于90的像素点变成纯黑
pixdata[x, y] = (0, 0, 0, 255)
for y in range(img.size[1]):
for x in range(img.size[0]):
if pixdata[x, y][2] > 0: # 使RGB值中B大于0的像素点变成纯白
pixdata[x, y] = (255, 255, 255, 255)
# 二次二值化(除去某些R、G、B值接近255的颜色)
for y in range(img.size[1]):
for x in range(img.size[0]):
if pixdata[x, y][0] < 254:
pixdata[x, y] = (0, 0, 0, 255)
for y in range(img.size[1]):
for x in range(img.size[0]):
if pixdata[x, y][1] < 254:
pixdata[x, y] = (0, 0, 0, 255)
for y in range(img.size[1]):
for x in range(img.size[0]):
if pixdata[x, y][2] > 0:
pixdata[x, y] = (255, 255, 255, 255)
# 三次二值化,怼掉纯黄色(实际使用中发现很多图片最后剩几个纯黄色的像素点)
for y in range(img.size[1]):
for x in range(img.size[0]):
if pixdata[x, y] == (255, 255, 0, 255):
pixdata[x, y] = (0, 0, 0, 255)
img.save(dir+"Bver.png","png")
#一次清除黑点
def Desiccation ():
white = (255,255,255,255)
black = (0,0,0,255)
img = Image.open(dir+"Bver.png") # 读入图片
pixdata = img.load()
X = img.size[0]-1#获取图像xy长度
Y = img.size[1]-1
def icolor(RGBA):
if RGBA == white:
return(1)
else:
return(0)
#填充黑点
for y in range(Y):
for x in range(X):
if x<1 or y<1:
pass
else:
if icolor(pixdata[x,y]) == 1:#判断为白色
pass
else:
if (
icolor(pixdata[x+1,y])+
icolor(pixdata[x,y+1])+
icolor(pixdata[x-1,y])+
icolor(pixdata[x,y-1])+
icolor(pixdata[x-1,y-1])+
icolor(pixdata[x+1,y-1])+
icolor(pixdata[x-1,y+1])+
icolor(pixdata[x+1,y+1])
)>5:
#如果一个黑色像素周围的8个像素中白色像素数量大于5个,则判断其为噪点,填充为白色
pixdata[x,y] = white
#填充白点
for y in range(Y):
for x in range(X):
if x<1 or y<1:
pass
else:
if icolor(pixdata[x,y]) == 0:
pass
else:
if (
(icolor(pixdata[x+1,y]))+
(icolor(pixdata[x,y+1]))+
(icolor(pixdata[x-1,y]))+
(icolor(pixdata[x,y-1]))
)<2:#白色数量小于两个,则黑色数量大于两个
#如果一个白色像素上下左右4个像素中黑色像素的个数大于2个,则判定其为有效像素,填充为黑色。
pixdata[x,y] = black
#二次去除黑点
for y in range(Y):
for x in range(X):
if x<1 or y<1:
pass
else:
if icolor(pixdata[x,y]) == 1:
pass
else:
if (
icolor(pixdata[x+1,y])+
icolor(pixdata[x,y+1])+
icolor(pixdata[x-1,y])+
icolor(pixdata[x,y-1])
)>2:
pixdata[x,y] = white
img.save(dir+"Dver.png", "png")
def readcCode():
try:
img = Image.open(r"C:\Program Files\Python\Lib\site-packages\pytesseract\test-european.jpg")
text = pytesseract.image_to_string(img)
text = text.replace(' ', '')
if text == "":#如果识别结果为空,则识别失败
tip = False
if re.search(r'[0-9a-zA-Z]{4}',text):
pass
else:
tip = False#如果识别结果中出现了了字母数字之外的字符,则识别失败
if len(text) !=4:
tip = False#如果识别结果不足四位(因为有部分字符粘连的验证码),则识别失败
except UnicodeDecodeError as e:
tip = False #如果报字符编码错误,则识别失败,需要捕捉错误
if tip == False:
#识别失败
return (readcCode())#如果识别失败,迭代、重新识别(实际使用中需要调用验证码获取函数重新获取验证码)
else:
return(text)
#getVerificationCode()
#Binarization()
#Desiccation()
text=readcCode()
print(text)
处理一般 验证码
和 我们学校的URP系统验证码
结果对比: