使用Python生成基礎驗證碼教程
阿新 • • 發佈:2018-11-19
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