Python + Flask 實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼系統(tǒng)
一、寫在前面
現(xiàn)在無(wú)論大大小小的網(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í)候,有沒(méi)有考慮過(guò)其背后的原理呢?當(dāng)然了,對(duì)于那些復(fù)雜的驗(yàn)證碼我們想要弄得一清二楚還是很難的,但是可以挑軟柿子捏嘛--字符圖形驗(yàn)證碼,就這樣,我決定用 Python + Flask 制作出一個(gè)簡(jiǎn)單的驗(yàn)證碼系統(tǒng)來(lái),話不多說(shuō),擼起袖子加油干!

二、基本思路
一個(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ù)操作,若失敗則給出提示信息并要求重新輸入。
但是沒(méi)有大量驗(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)提過(guò)這一步主要使用的模塊是 pillow,沒(méi)有安裝的話可以使用 pip install pillow 進(jìn)行安裝。
PIL:Python Image Library,是 Python 處理圖片的標(biāo)準(zhǔn)庫(kù),不過(guò) 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)在的問(wèn)題就是如何將驗(yàn)證碼圖片顯示在頁(yè)面上,要解決這個(gè)問(wèn)題,首先要定義一個(gè)路由,用于隨機(jī)選取驗(yàn)證碼圖片并返回路徑。
在 Flask 中 route() 裝飾器把一個(gè)函數(shù)綁定到 URL 上,不僅能配置靜態(tài) URL,而且能配置動(dòng)態(tài) URL,不過(guò)這里使用靜態(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)證碼圖片的功能可以通過(guò)使用 Ajax 來(lái)實(shí)現(xiàn),主要過(guò)程是先向后端發(fā)送請(qǐng)求,請(qǐng)求成功之后會(huì)得到一個(gè)驗(yàn)證碼圖片路徑, 然后再設(shè)置圖片的 src 屬性,達(dá)到刷新驗(yàn)證碼的目的。在 Ajax 中的 URL 可以直接寫靜態(tài) URL,還能使用 url_for 來(lái)反向解析獲取對(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)容來(lái)命名的,所以這里就可以用 JavaScript 來(lái)獲取圖片名稱,再將輸入框中的內(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)就做出來(lái)了,當(dāng)然還有很多可以去完善的地方,比如使用更復(fù)雜的驗(yàn)證碼,對(duì)驗(yàn)證次數(shù)進(jìn)行限制等等。
完整代碼已上傳到 GitHub!
總結(jié)
以上所述是小編給大家介紹的Python + Flask 制作一個(gè)簡(jiǎn)單的驗(yàn)證碼系統(tǒng),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)歡迎給我留言,小編會(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框架開(kāi)發(fā)驗(yàn)證碼登錄的實(shí)現(xiàn)
- Flask 驗(yàn)證碼自動(dòng)生成的實(shí)現(xiàn)示例
相關(guān)文章
Django使用 Bootstrap 樣式修改書籍列表過(guò)程解析
這篇文章主要介紹了Django使用 Bootstrap 樣式修改書籍列表過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
python 畫3維軌跡圖并進(jìn)行比較的實(shí)例
今天小編就為大家分享一篇python 畫3維軌跡圖并進(jìn)行比較的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
Python實(shí)戰(zhàn)之能監(jiān)控文件變化的神器—看門狗
這篇文章主要介紹了Python實(shí)戰(zhàn)之能監(jiān)控文件變化的神器—看門狗,文中有非常詳細(xì)的圖文及代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-05-05
django 鏈接多個(gè)數(shù)據(jù)庫(kù) 并使用原生sql實(shí)現(xiàn)
這篇文章主要介紹了django 鏈接多個(gè)數(shù)據(jù)庫(kù) 并使用原生sql實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03

