利用Python實(shí)現(xiàn)生成并識(shí)別圖片驗(yàn)證碼
本次來分享一個(gè)關(guān)于驗(yàn)證碼的知識(shí),在登錄網(wǎng)站時(shí),為了確保是人在操作,一般會(huì)要求輸入圖片上的驗(yàn)證碼。那么這個(gè)驗(yàn)證碼要怎么生成呢?以及在做爬蟲的時(shí)候,怎么用機(jī)器來識(shí)別呢?
圍繞著這兩個(gè)問題,我們開始今天的內(nèi)容。
生成驗(yàn)證碼
所謂驗(yàn)證碼就是一張圖片,圖片上有一些數(shù)字和字母。所以我們只要生成一張圖片,然后在圖片上寫一些內(nèi)容即可。
使用 PIL 模塊可以非常方便做到這一點(diǎn),沒有安裝的話,需要執(zhí)行 pip install pillow。
from random import randint, sample import string from PIL import Image, ImageFont, ImageDraw # 隨機(jī)生成畫板顏色 bg_color = randint(0, 255), randint(0, 255), randint(0, 255) # 定義畫板的寬和高 width, height = 200, 80 # 創(chuàng)建畫板對(duì)象 im = Image.new("RGB", (width, height), bg_color) # 創(chuàng)建畫筆對(duì)象,接收畫板對(duì)象 # 這樣一來,畫筆所畫的內(nèi)容都會(huì)顯示在畫板上 draw = ImageDraw.Draw(im) # 繪制噪點(diǎn),噪點(diǎn)的數(shù)量一般為 width * height * 0.1 for _ in range(int(width * height * 0.1)): # 噪點(diǎn)的橫縱坐標(biāo) point_pos = randint(0, width), randint(0, height) # 噪點(diǎn)的顏色,盡量也是隨機(jī)的 point_color = randint(0, 255), randint(0, 255), randint(0, 255) # 繪制 draw.point(point_pos, point_color) # 查看繪制的圖片 im.show()
執(zhí)行代碼,會(huì)生成圖片,我們看一下長(zhǎng)什么樣子。
可以看到噪點(diǎn)此刻繪制出來了,再為其繪制幾條直線和曲線。
# 直線的長(zhǎng)度要從畫板的左邊到畫板的右邊 # 因此左端點(diǎn)要在畫板左側(cè)上下變化,右端點(diǎn)要在畫板右側(cè)上下變化 for _ in range(5): left_pos = 0, randint(0, height) right_pos = width, randint(0, height) line_color = randint(0, 255), randint(0, 255), randint(0, 255) # 繪制直線 draw.line([left_pos, right_pos], line_color) # 繪制曲線,這里繪制的是一個(gè)超出畫板的大圓 # 這樣在畫板上顯示的部分只是大圓的一條弧,看起來就像是一條曲線 for _ in range(5): left_pos = (-100, -100) right_pos = (width * 5, randint(0, height)) arc_color = randint(0, 255), randint(0, 255), randint(0, 255) draw.arc([left_pos, right_pos], 0, 360, arc_color) # 查看一下,繪制的圖形長(zhǎng)什么樣子 im.show()
直線和曲線也繪制好了,看下效果。
效果還是不錯(cuò)的,最后我們來繪制文字。
# 驗(yàn)證碼是由文字和數(shù)字組成,先來獲取所有的數(shù)字和字母 alpha_digit = string.ascii_letters + string.digits # 驗(yàn)證碼一般是四個(gè)字符,從里面隨機(jī)選取4個(gè) verify_code = sample(alpha_digit, 4) # 生成字體對(duì)象 font = ImageFont.truetype("/System/Library/Fonts/Courier.ttc", 40) # 為四個(gè)字符創(chuàng)建四種顏色 text_color = [(randint(0, 255), randint(0, 255), randint(0, 255)) for _ in range(4)] # 繪制文字 # 注意:坐標(biāo)加上字體的寬度不要超出畫板,否則顯示不全 draw.text((10, 10), verify_code[0], fill=text_color[0], font=font) draw.text((60, 25), verify_code[1], fill=text_color[1], font=font) draw.text((110, 15), verify_code[2], fill=text_color[2], font=font) draw.text((150, 25), verify_code[3], fill=text_color[3], font=font) # 繪制完成,最后再查看一下 im.show()
到此我們的驗(yàn)證碼就生成完畢了,那么效果如何呢?我們查看一下。
整體來看還湊合,你也可以對(duì)背景色,以及文字的顏色進(jìn)行調(diào)整。如果覺得背景里的噪點(diǎn)、線段不太好,也可以將它們?nèi)サ簟?/p>
最后再來說說保存,代碼中的 im.show() 實(shí)際上是打開了一個(gè)臨時(shí)文件,我們?nèi)绾螌⑺4嫦聛砟兀?/p>
# 可以輸入一個(gè)路徑,然后保存成指定的文件 # 不過更常見的做法是拿到圖片的字節(jié)流,然后直接對(duì)字節(jié)流進(jìn)行渲染 from io import BytesIO buf = BytesIO() im.save(buf, "png") # 此時(shí)圖片內(nèi)容就保存在了 buf 中 print(buf.getvalue()[: 6] == b"\x89PNG\r\n") # True
以上就是繪制驗(yàn)證碼的過程,代碼是分塊展示的,你可以將它們合在一起,測(cè)試一下。
識(shí)別驗(yàn)證碼
說完了生成驗(yàn)證碼,那么如何識(shí)別驗(yàn)證碼呢?Python 有一個(gè)第三方庫 ddddocr,可以幫我們識(shí)別,直接 pip install ddddocr 安裝即可。
我們目前已經(jīng)生成了一張驗(yàn)證碼:
這里補(bǔ)充一句,我們上面生成的驗(yàn)證碼圖片,在顏色上設(shè)計(jì)的不太好,因?yàn)楸尘吧臀淖诸伾际请S機(jī)的,這就導(dǎo)致當(dāng)顏色相近時(shí),看不清文字內(nèi)容。
而當(dāng)文字顏色和背景色比較接近時(shí),ddddocr 識(shí)別的準(zhǔn)確率就會(huì)降低很多,特別是背景中還有噪點(diǎn)和線段作為干擾。不過一般來說網(wǎng)站的驗(yàn)證碼圖片都是經(jīng)過設(shè)計(jì)的,背景色和文字顏色區(qū)別還是比較大的,所以不用擔(dān)心。
我們測(cè)試一下:
import ddddocr with open("code.png", "rb") as f: data = f.read() # show_ad 默認(rèn)為 True,執(zhí)行時(shí)會(huì)輸出一些廣告,我們不讓它輸出 ocr = ddddocr.DdddOcr(show_ad=False) code = ocr.classification(data) print(code) # 7abf
結(jié)果沒有問題,識(shí)別出來了。
到此這篇關(guān)于利用Python實(shí)現(xiàn)生成并識(shí)別圖片驗(yàn)證碼的文章就介紹到這了,更多相關(guān)Python圖片驗(yàn)證碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TensorFlow dataset.shuffle、batch、repeat的使用詳解
今天小編就為大家分享一篇TensorFlow dataset.shuffle、batch、repeat的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01Python 合并多個(gè)TXT文件并統(tǒng)計(jì)詞頻的實(shí)現(xiàn)
這篇文章主要介紹了Python 合并多個(gè)TXT文件并統(tǒng)計(jì)詞頻的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08使用tensorflow實(shí)現(xiàn)VGG網(wǎng)絡(luò),訓(xùn)練mnist數(shù)據(jù)集方式
這篇文章主要介紹了使用tensorflow實(shí)現(xiàn)VGG網(wǎng)絡(luò),訓(xùn)練mnist數(shù)據(jù)集方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05python的schedule定時(shí)任務(wù)模塊二次封裝方法
今天小編就為大家分享一篇python的schedule定時(shí)任務(wù)模塊二次封裝方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02python 申請(qǐng)內(nèi)存空間,用于創(chuàng)建多維數(shù)組的實(shí)例
今天小編就為大家分享一篇python 申請(qǐng)內(nèi)存空間,用于創(chuàng)建多維數(shù)組的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12python計(jì)算階乘和的方法(1!+2!+3!+...+n!)
今天小編就為大家分享一篇python計(jì)算階乘和的方法(1!+2!+3!+...+n!),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02Pytorch中使用ImageFolder讀取數(shù)據(jù)集時(shí)忽略特定文件
這篇文章主要介紹了Pytorch中使用ImageFolder讀取數(shù)據(jù)集時(shí)忽略特定文件,具有一的參考價(jià)值需要的小伙伴可以參考一下,希望對(duì)你有所幫助2022-03-03python docx段落對(duì)齊實(shí)現(xiàn)方式
python-docx庫是一個(gè)用于創(chuàng)建和更新MicrosoftWord文檔的庫,提供了豐富的功能,包括段落對(duì)齊方式設(shè)置,段落對(duì)齊方式可以通過Paragraph對(duì)象的alignment屬性來設(shè)置,常用的對(duì)齊方式包括左對(duì)齊、右對(duì)齊、居中對(duì)齊、兩端對(duì)齊等2024-11-11