用python編寫驗證碼
作為一個用python的生信工程師,平時工作中除了用python來處理些文字檔案和搭建流程,沒事也想探索些其他有趣的功能。這幾天就在網上學習了下如何用python編寫驗證碼,感興趣的同學也一起來學習下吧!
01
驗證碼的作用及干擾機制
在編寫驗證碼之前,我們首先來了解下驗證碼是用來幹嘛的吧:
驗證碼主要是為了防止暴力破解,爬蟲模擬登陸以及各種鍵盤鉤子進行登陸;驗證碼能起到干擾作用的機制主要是靠背景點或線條進行干擾,以及對文字進行扭曲。
02
Python編寫驗證碼實戰
我們先來看下采用python編寫驗證碼的一個基本思路:
1.定義一張圖片
2.建立畫筆
3.繪製線條和點
4.繪製文字
5.定義扭曲的引數
6.使用濾鏡
下面我們分步來看一下每一步的程式碼實現是怎樣的吧(注:這裡採用的是python2進行編寫):
01
匯入模組
import randomfrom PIL import Image,ImageDraw,ImageFont,ImageFilter
這裡我們需要用到兩個模組,random模組和PTL模組。random模組用來生成隨機數,PIL是一個用來處理圖片檔案的python第三方模組。PIL沒有安裝的小夥伴可以採用pip install PIL進行安裝。PIL中的Image類負責處理圖片,ImageDraw負責處理畫筆, ImageFont負責處理字型,ImageFilter負責處理濾鏡。
02
定義一張圖片
img = Image.new("RGB",(150,50),(255,255,255))
這裡需要用到三個引數,分別代表我們採用RGB顏色模式,圖片的大小,具體的圖片顏色。
03
建立畫筆
draw = ImageDraw.Draw(img)
04
繪製線條和點
繪製線條
for i in range(random.randint(1,10)): draw.line( #在繪製線條時:每條線有兩個點,每個點靠x,y兩個值來確定位置 [ ( random.randint(1,150),random.randint(1,150)),( random.randint(1,150),random.randint(1,150)) ], fill = (0,0,0) )
這裡random.randint(1,10)函式用來生成1-10之間的隨機數,draw.line是用來繪製線條的函式,由於一條線是由兩個點組成,所以這裡我們採用列表來儲存線條的起止座標。由於驗證碼中線條的作用就是起干擾作用,所以我們需要繪製出來的線條是沒有規律的。這裡迴圈用以生成線條的條數以及線條的起止座標都採用random函式來隨機生成。fill用來給出線條的RGB顏色。
繪製點
for i in range(2000):
draw.point(
(random.randint(1,150),random.randint(1,150)),
fill =(0,0,0)
)
同理,我們可以繪製隨機座標的點,這裡可以用迴圈控制繪製點的數量。
05
繪製文字
fontList = list("abdfkjfalemvcjierASDFGHJKLQW123456789")
c_chars = " ".join(random.sample(fontList,5)
#random.sample是在指定的列表當中隨機取出指定個元素
font = ImageFont.truetype("simsun.ttc",26)
draw.text((5,5),c_chars,font=font,fill="green")
接下來我們就要繪製顯示在驗證碼上的文字啦,在繪製文字的時候我們要考慮兩點,首先我們生成的文字是要隨機產生的,另外文字的個數需要是固定的。
這裡我們首先利用fontList變數來定義要生成的隨機數的字母和數字,接著我們要從定義的隨機數列表當中取出指定個數的隨機數。這裡就要用到random.sample這個函式啦,函式後面接的引數就是取出的隨機數的個數,其後我們用join函式將取出的隨機數列表連線成字串。隨後用ImageFont.truetype定義字型,函式的第一個引數代表字型類別,第二個引數代表字型大小。最後採用draw.text進行文字的最終繪製,這裡第一個引數代表文字的位置,距離上和左方的距離,第二個引數代表文字的內容,第三個引數代表字型,第四個引數定義字型的顏色。
06
定義扭曲引數
params = [1 - float(random.randint(1,2))/100,
0,
0,
0,
1 - float(random.randint(1,2))/100,
float(random.randint(1,2))/500,
0.001,
float(random.randint(1,1))/500,
]
這裡的引數有點多,這裡就不詳細介紹每個數值的含義啦,感興趣的小夥伴可以自行百度搜索一下。
07
使用濾鏡
img = img.transform((150,50),Image.PERSPECTIVE,params) # 建立扭曲
"""
第一個引數:扭曲的範圍,
第二個引數:扭曲的樣式,
第三個引數:扭曲的引數
"""
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) #濾鏡,邊界加強(閾值更大)
img.show()
接下來我們就要使用濾鏡來對文字進行扭曲,首先使用img.transform這個函式來建立扭曲,其中的三個引數,分別代表扭曲的範圍、扭曲的樣式、扭曲的引數,接著使用img.filter來進行扭曲。
最後我們來看下生成的效果吧:
是不是很簡單呢,上述程式碼我們也可以封裝成函式進行編寫,感興趣的小夥伴們可以自己動手試下哦。
我們在學習python的過程中可以多找一些自己感興趣的專案來練習提高自己的程式設計能力,比如多練習下生信技能樹中的生信程式設計題,也可以找一些自己感興趣的應用來學習,比如試著用爬蟲爬取自己感興趣的內容,也可以試著用python寫一些小遊戲玩玩,人生苦短,我用python,讓我們一起在學習練習中進步吧!