使用Python生成基础验证码教程
pillow是Python平台事实上的图像处理标准库。PIL功能非常强大,但API却非常简单易用。 所以我们使用它在环境里做图像的处理。
第一步 下载pillow
#运行命令 pip install pillow
第二部 编写代码
1>创建一个类,初始化并为类添加属性
我们可能需要的属性有:验证码图片宽高,干扰点线数量,我们要出现多少个验证码等
2>随机生成背景颜色和字体颜色,在此建议将背景色生成范围定为浅色(0-120),字体色为深色(120-255)易于人眼识别
3>创建画布并依次画线点字,如果需要将字体倾斜旋转需要拷贝原图旋转再与原图合成
4>返回验证码图片和验证码答案字符串
例:
from PIL import Image,ImageDraw,ImageFont import random import io class code: def __init__(self): self.width=120 //生成验证码图片的宽度 self.height=40 //生成验证码图片的高度 self.im=None self.lineNum=None //生成干扰线的数量 self.pointNum=None //生成干扰点的数量 self.codecon="QWERTYUPASDFGHJKZXCVBNMqwertyupadfhkzxcvbnm0123456789" //验证码出现的字符 self.codelen=4 //验证码出现字符的数量 self.str="" def randBgColor(self): return (random.randint(0,120),random.randint(0,120),random.randint(0,120)) def randFgColor(self): return (random.randint(120, 255), random.randint(120, 255), random.randint(120, 255)) def create(self): self.im = Image.new('RGB', size=(self.width, self.height), color=self.randBgColor()) def lines(self): lineNum=self.lineNum or random.randint(3,6) draw = ImageDraw.Draw(self.im) for item in range(lineNum): place=(random.randint(0,self.width),random.randint(0,self.height),random.randint(0,self.height),random.randint(0,self.height)) draw.line(place,fill=self.randFgColor(),width=random.randint(1,3)) def point(self): pointNum = self.pointNum or random.randint(30, 60) draw = ImageDraw.Draw(self.im) for item in range(pointNum): place=(random.randint(0,self.width),random.randint(0,self.height)) draw.point(place,fill=self.randFgColor()) def texts(self): draw = ImageDraw.Draw(self.im) for item in range(self.codelen): x=item*self.width/self.codelen+random.randint(-self.width/15,self.width/15) y=random.randint(-self.height/10,self.height/10) text=self.codecon[random.randint(0,len(self.codecon)-1)] self.str+=text fnt = ImageFont.truetype('ARVO-REGULAR.TTF', random.randint(30,38)) draw.text((x,y),text,fill=self.randFgColor(),font=fnt,rotate="180") def output(self): self.create() self.texts() self.lines() self.point() bt=io.BytesIO() self.im.save(bt,"png") return bt.getvalue()
5>将验证码渲染到网页中,以Flask为例
<img src="/codeimg" alt="" width="120" height="40">
@app.route('/codeimg')
def codeimg(): codeobj=code() res=make_response(codeobj.output()) session["code"]=codeobj.str.lower() res.headers["content-type"]="image/png" return res
简单的输入式验证码就完成了,如有错误之处欢迎指正。
破解验证码时我们要用到第三方库。
解决思路:因为这种是最简单的一种验证码,只要识别出里面的内容,然后填入到输入框中即可。这种识别技术叫OCR,这里推荐使用Python的第三方库,tesserocr。对于有嘈杂的背景的验证码这种,直接识别识别率会很低,遇到这种我们就得需要先处理一下图片,先对图片进行灰度化,然后再进行二值化,再去识别,这样识别率会大大提高。
同样也可以参考使用pillow处理识别,链接https://blog.csdn.net/qq_35923581/article/details/79487579
学而不用则罔 用而不学则殆