【Python~分享】爬取学校的 URP 系统

注:这个是我当初爬学校的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系统验证码 结果对比:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值