Python + Flask 實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼系統(tǒng)
一、寫在前面
現(xiàn)在無論大大小小的網(wǎng)站,基本上都會(huì)使用驗(yàn)證碼,登錄的時(shí)候要驗(yàn)證,下載的時(shí)候要驗(yàn)證,而使用的驗(yàn)證碼也從那些簡(jiǎn)簡(jiǎn)單單的字符圖形驗(yàn)證碼“進(jìn)化”成了需要進(jìn)行圖文識(shí)別的驗(yàn)證碼、需要拖動(dòng)滑塊的滑動(dòng)驗(yàn)證碼、甚至還有手機(jī)驗(yàn)證碼。當(dāng)你與之打交道的時(shí)候,有沒有考慮過其背后的原理呢?當(dāng)然了,對(duì)于那些復(fù)雜的驗(yàn)證碼我們想要弄得一清二楚還是很難的,但是可以挑軟柿子捏嘛--字符圖形驗(yàn)證碼,就這樣,我決定用 Python + Flask 制作出一個(gè)簡(jiǎn)單的驗(yàn)證碼系統(tǒng)來,話不多說,擼起袖子加油干!
二、基本思路
一個(gè)簡(jiǎn)單的驗(yàn)證碼系統(tǒng),要實(shí)現(xiàn)的目標(biāo)包括能夠不斷刷新驗(yàn)證碼和對(duì)用戶輸入的內(nèi)容進(jìn)行驗(yàn)證,若驗(yàn)證成功則進(jìn)行后續(xù)操作,若失敗則給出提示信息并要求重新輸入。
但是沒有大量驗(yàn)證碼圖片怎么辦呢?正所謂“自己動(dòng)手,豐衣足食”,Python 所具有的豐富的第三方庫(kù)使得產(chǎn)生大量驗(yàn)證碼圖片這一需求變得甚是簡(jiǎn)單了,這里主要使用的模塊是 pillow。
有了驗(yàn)證碼圖片之后,要做的就是將其顯示在前端頁(yè)面上,并且要能夠更新驗(yàn)證碼,這利用 Flask 可以很方便地實(shí)現(xiàn)。然后就是輸入驗(yàn)證碼和對(duì)輸入的內(nèi)容進(jìn)行驗(yàn)證了,這里我是用 JS 實(shí)現(xiàn)驗(yàn)證的。
三、具體步驟
1.生成驗(yàn)證碼圖片
前面已經(jīng)提過這一步主要使用的模塊是 pillow,沒有安裝的話可以使用 pip install pillow 進(jìn)行安裝。
PIL:Python Image Library,是 Python 處理圖片的標(biāo)準(zhǔn)庫(kù),不過 PIL 僅支持到 Python2.7,之后有人在其基礎(chǔ)上創(chuàng)建了兼容的版本,名字就叫做 pillow。
新建一個(gè) Flask 項(xiàng)目:CaptchaTest,然后創(chuàng)建一個(gè) generate.py。要生成一個(gè)驗(yàn)證碼圖片,首先得創(chuàng)建一張圖片,可以用 pillow 模塊中的 Image.new() 實(shí)現(xiàn)。然后需要生成驗(yàn)證碼文本并將其寫入到前面生成的圖片上,除此之外,我們還可以加入一些干擾元素增加識(shí)別的難度。下面是幾張生成的驗(yàn)證碼圖片:
最終得到的生成驗(yàn)證碼圖片的代碼如下:
from random import randint from PIL import Image, ImageDraw, ImageFont def get_random_color(): # 隨機(jī)顏色RGB return randint(120, 200), randint(120, 200), randint(120, 200) def get_random_code(): # 隨機(jī)字符 codes = [[chr(i) for i in range(48, 58)], [chr(i) for i in range(65, 91)], [chr(i) for i in range(97, 123)]] codes = codes[randint(0, 2)] return codes[randint(0, len(codes)-1)] def generate_captcha(width=140, height=60, length=4): # 生成驗(yàn)證碼 img = Image.new("RGB", (width, height), (250, 250, 250)) draw = ImageDraw.Draw(img) font = ImageFont.truetype("static/font/font.ttf", size=36) # 驗(yàn)證碼文本 text = "" for i in range(length): c = get_random_code() text += c rand_len = randint(-5, 5) draw.text((width * 0.2 * (i+1) + rand_len, height * 0.2 + rand_len), c, font=font, fill=get_random_color()) # 加入干擾線 for i in range(3): x1 = randint(0, width) y1 = randint(0, height) x2 = randint(0, width) y2 = randint(0, height) draw.line((x1, y1, x2, y2), fill=get_random_color()) # 加入干擾點(diǎn) for i in range(16): draw.point((randint(0, width), randint(0, height)), fill=get_random_color()) # 保存圖片 img.save("static/captcha/" + text + ".jpg") return text + ".jpg" if __name__ == "__main__": for i in range(1000): generate_captcha()
2.顯示驗(yàn)證碼圖片
在進(jìn)行完上一步之后,我們已經(jīng)得到了1000張驗(yàn)證碼圖片,都保存在 static 下的 captcha 文件夾下。那么現(xiàn)在的問題就是如何將驗(yàn)證碼圖片顯示在頁(yè)面上,要解決這個(gè)問題,首先要定義一個(gè)路由,用于隨機(jī)選取驗(yàn)證碼圖片并返回路徑。
在 Flask 中 route() 裝飾器把一個(gè)函數(shù)綁定到 URL 上,不僅能配置靜態(tài) URL,而且能配置動(dòng)態(tài) URL,不過這里使用靜態(tài) URL 就行了。定義該路由的代碼如下:
@app.route('/get_captcha', methods=['GET']) def get_captcha(): img_list = os.listdir("static/captcha") img = img_list[random.randint(0, 1000)] return os.path.join("static/captcha", img)
其中 os.listdir() 用于列舉文件夾下的內(nèi)容,os.path.join() 用于返回圖片路徑。
3.刷新驗(yàn)證碼圖片
刷新驗(yàn)證碼圖片的功能可以通過使用 Ajax 來實(shí)現(xiàn),主要過程是先向后端發(fā)送請(qǐng)求,請(qǐng)求成功之后會(huì)得到一個(gè)驗(yàn)證碼圖片路徑, 然后再設(shè)置圖片的 src 屬性,達(dá)到刷新驗(yàn)證碼的目的。在 Ajax 中的 URL 可以直接寫靜態(tài) URL,還能使用 url_for 來反向解析獲取對(duì)應(yīng)的 URL,使用方法如下:
<script> function Change() { $.ajax({ url: '{{ url_for('get_captcha') }}', async: true, type: "GET", success: function (data) { document.getElementById("captcha").src = data; } }) } </script>
4.驗(yàn)證碼內(nèi)容驗(yàn)證
在輸入驗(yàn)證碼內(nèi)容后,需要對(duì)輸入的內(nèi)容進(jìn)行驗(yàn)證。因?yàn)榍懊嫔沈?yàn)證碼圖片的時(shí)候直接用的圖片內(nèi)容來命名的,所以這里就可以用 JavaScript 來獲取圖片名稱,再將輸入框中的內(nèi)容獲取到,把兩者進(jìn)行比對(duì),這一步還可以做一個(gè)忽略大小寫,至于具體代碼就不放了。
四、運(yùn)行截圖
首先是一張運(yùn)行頁(yè)面的截圖,點(diǎn)擊“看不清楚,換一張”可以刷新驗(yàn)證碼,點(diǎn)擊“確認(rèn)”可以驗(yàn)證輸入的內(nèi)容是否正確:
當(dāng)輸入的內(nèi)容正確的時(shí)候,給出一個(gè)驗(yàn)證成功的提示:
到這里為止,一個(gè)簡(jiǎn)單的驗(yàn)證碼系統(tǒng)就做出來了,當(dāng)然還有很多可以去完善的地方,比如使用更復(fù)雜的驗(yàn)證碼,對(duì)驗(yàn)證次數(shù)進(jìn)行限制等等。
完整代碼已上傳到 GitHub!
總結(jié)
以上所述是小編給大家介紹的Python + Flask 制作一個(gè)簡(jiǎn)單的驗(yàn)證碼系統(tǒng),希望對(duì)大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
- python web框架Flask實(shí)現(xiàn)圖形驗(yàn)證碼及驗(yàn)證碼的動(dòng)態(tài)刷新實(shí)例
- flask實(shí)現(xiàn)驗(yàn)證碼并驗(yàn)證功能
- Flask項(xiàng)目中實(shí)現(xiàn)短信驗(yàn)證碼和郵箱驗(yàn)證碼功能
- Python Flask實(shí)現(xiàn)圖片驗(yàn)證碼與郵箱驗(yàn)證碼流程詳細(xì)講解
- 基于Python+Flask實(shí)現(xiàn)一個(gè)簡(jiǎn)易網(wǎng)頁(yè)驗(yàn)證碼登錄系統(tǒng)案例
- Python的Flask框架開發(fā)驗(yàn)證碼登錄的實(shí)現(xiàn)
- Flask 驗(yàn)證碼自動(dòng)生成的實(shí)現(xiàn)示例
相關(guān)文章
Python?中的?Counter?模塊及使用詳解(搞定重復(fù)計(jì)數(shù))
Counter 是一個(gè)簡(jiǎn)單的計(jì)數(shù)器,用于統(tǒng)計(jì)某些可哈希對(duì)象的數(shù)量。它以字典的形式存儲(chǔ)元素和它們的計(jì)數(shù),這篇文章主要介紹了Python?中的?Counter?模塊及使用詳解(搞定重復(fù)計(jì)數(shù)),需要的朋友可以參考下2023-04-04python實(shí)現(xiàn)數(shù)據(jù)分析與建模
這篇文章主要介紹了python實(shí)現(xiàn)數(shù)據(jù)分析與建模功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07Python詳解argparse參數(shù)模塊之命令行參數(shù)
這篇文章主要介紹了Python詳解argparse參數(shù)模塊之命令行參數(shù),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考下面文章詳解2022-07-07