引入
基本上大家使用每一種網路服務都會遇到驗證碼,一般是網站為了防止惡意註冊、發帖而設定的驗證手段。其生成原理是將一串隨機產生的數字或符號,生成一幅圖片,圖片里加上一些干擾象素(防止OCR)。下面就詳細講解如何生成驗證碼。
所需環境
除了配置好的python環境外,還需要配有python中的PIL庫,這是python中專門用來處理圖片的庫。用傳統的pip install 方法或者下載原始碼 python setup.py install 方法安裝該庫,很可能會報錯(視執行環境不同)。可以採用以下方法
1 2 3 4 5 6 |
1.下載安裝包URL:http://www.pythonware.com/products/pil/index.htm,要下載支援全平臺的。 2.解壓縮: tar –zxv –f Imaging-1.1.7.tar.gz 3.進入到解壓後的目錄: cd Imaging-1.1.7 4.Bulid pakage:python setup.py build_ext –i 5.測試:python selftest.py 6.安裝:python setup.py install |
程式碼實現
要生成驗證碼圖片,我們首先要生成一個隨機字串,包含26個字母和10個數字。
1 2 3 4 5 6 |
#用來隨機生成一個字串 def gene_text(): source = list(string.letters) for index in range(0,10): source.append(str(index)) return ''.join(random.sample(source,number))#number是生成驗證碼的位數 |
然後我們要建立一個圖片,寫入字串,需要說明的這裡面的字型是不同系統而定,如果沒有找到系統字型路徑的話,也可以不設定
1 2 3 4 5 6 7 8 9 |
def gene_code(): width,height = size #寬和高 image = Image.new('RGBA',(width,height),bgcolor) #建立圖片 font = ImageFont.truetype(font_path,25) #驗證碼的字型和字型大小 draw = ImageDraw.Draw(image) #建立畫筆 text = gene_text() #生成字串 font_width, font_height = font.getsize(text) draw.text(((width - font_width) / number, (height - font_height) / number),text, font= font,fill=fontcolor) #填充字串 |
接下來,我們要在圖片上畫幾條干擾線
1 2 3 4 5 |
#用來繪製干擾線 def gene_line(draw,width,height): begin = (random.randint(0, width), random.randint(0, height)) end = (random.randint(0, width), random.randint(0, height)) draw.line([begin, end], fill = linecolor) |
最後建立扭曲,加上濾鏡,用來增強驗證碼的效果。
1 2 3 |
image = image.transform((width+20,height+10), Image.AFFINE, (1,-0.3,0,-0.1,1,0),Image.BILINEAR) #建立扭曲 image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) #濾鏡,邊界加強 image.save('idencode.png') #儲存驗證碼圖片 |
下面是用上述程式生成的一個驗證碼
下面是完整的程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#coding=utf-8 import random import string import sys import math from PIL import Image,ImageDraw,ImageFont,ImageFilter #字型的位置,不同版本的系統會有不同 font_path = '/Library/Fonts/Arial.ttf' #生成幾位數的驗證碼 number = 4 #生成驗證碼圖片的高度和寬度 size = (100,30) #背景顏色,預設為白色 bgcolor = (255,255,255) #字型顏色,預設為藍色 fontcolor = (0,0,255) #干擾線顏色。預設為紅色 linecolor = (255,0,0) #是否要加入干擾線 draw_line = True #加入干擾線條數的上下限 line_number = (1,5) #用來隨機生成一個字串 def gene_text(): source = list(string.letters) for index in range(0,10): source.append(str(index)) return ''.join(random.sample(source,number))#number是生成驗證碼的位數 #用來繪製干擾線 def gene_line(draw,width,height): begin = (random.randint(0, width), random.randint(0, height)) end = (random.randint(0, width), random.randint(0, height)) draw.line([begin, end], fill = linecolor) #生成驗證碼 def gene_code(): width,height = size #寬和高 image = Image.new('RGBA',(width,height),bgcolor) #建立圖片 font = ImageFont.truetype(font_path,25) #驗證碼的字型 draw = ImageDraw.Draw(image) #建立畫筆 text = gene_text() #生成字串 font_width, font_height = font.getsize(text) draw.text(((width - font_width) / number, (height - font_height) / number),text, font= font,fill=fontcolor) #填充字串 if draw_line: gene_line(draw,width,height) # image = image.transform((width+30,height+10), Image.AFFINE, (1,-0.3,0,-0.1,1,0),Image.BILINEAR) #建立扭曲 image = image.transform((width+20,height+10), Image.AFFINE, (1,-0.3,0,-0.1,1,0),Image.BILINEAR) #建立扭曲 image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) #濾鏡,邊界加強 image.save('idencode.png') #儲存驗證碼圖片 if __name__ == "__main__": gene_code() |