【詳解】簡單驗證碼的解析
阿新 • • 發佈:2019-02-10
首先把大致思路說一下,解析驗證碼就是先獲取驗證碼圖片,然後通過Python的PIL庫以及其它相關庫,實現IMAGE_TO_STRING。
即,把圖片進行處理解析,輸出圖片中的數字或字母,就達到了解析驗證碼的目的。
經過研究,發現用這種方法進行準確的驗證碼解析並不現實,準確率太低了。而且不同網站的驗證碼生成方式都是不一樣的。
對比字型檔如果一直不變的話,對準確率也會產生影響。
我們目前找到的方法,對於相當簡單,一目瞭然的清晰驗證碼肯定是有效的。如純數字,解析很可靠。(理論上來說是這樣的)
對於B站的數字加字母,並且還發生扭曲重合的情況,最終我們還是隻能獲取驗證碼圖片,然後人工識別輸入。
接下來我們首先介紹識別簡單驗證碼的方法。
【識別簡單驗證碼】
首先貼出全部程式碼如下:
#!/usr/bin/python # -*- coding: utf-8 -*- __author__ = "$Author: wangxin.xie$" __version__ = "$Revision: 1.0 $" __date__ = "$Date: 2015-12-11 9:51$" ############################################################### # 功能:抓取驗證碼圖片,識別簡單驗證碼。。。但是準確率太低 ###############################################################import urllib2 import datetime import sys import os from pytesser import * #####################全域性變數########################################### today = datetime.datetime.today() todayStr = datetime.datetime.strftime(today, "%Y-%m-%d") lastDayDate = today - datetime.timedelta(1) lastDayDateStr = datetime.datetime.strftime(lastDayDate,"%Y-%m-%d") os.chdir('C:\Python27\Lib\site-packages\pytesser_v0.0.1') picname="vdcode.png" vdUrl="https://account.bilibili.com/captcha" ################################################################# def printStr(): # 二值化 threshold = 140 table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) #開啟圖片 im = Image.open(picname) #轉化到亮度 imgry = im.convert('L') #imgry.save('g'+picname) #二值化 out = imgry.point(table,'1') #out.save('b'+picname) #識別 text = image_to_string(out) #識別 text = text.strip() text = text.upper() text = text.replace(' ','') print text def checkVdCode(): resp=urllib2.urlopen(vdUrl) f = open(picname, 'wb') f.write(resp.read()) f.close() print('Pic Saved!') def main(): print "===%s start===%s"%(sys.argv[0], datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")) checkVdCode() printStr() print "===%s end===%s"%(sys.argv[0], datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")) ################################################################################# if __name__ == "__main__": main()
按程式的執行順序來進行解釋。
我們進入主函式,先進入
checkVdCode()獲取驗證碼圖片。圖片儲存路徑如下
os.chdir('C:\Python27\Lib\site-packages\pytesser_v0.0.1') picname="vdcode.png"
為何要將圖片放在pytesser的目錄下?
【ERROR2的報錯解決方法】
我們在編碼過程中,執行到
#識別 text = image_to_string(out)時,遇到過windows error2的報錯。error2的意思是系統找不到指定路徑。
網上找到的唯一解決辦法是,將驗證碼圖片的路徑引到pytesser的資料夾路徑下。所以就只能
os.chdir('C:\Python27\Lib\site-packages\pytesser_v0.0.1') picname="vdcode.png"
顯示了Pic Saved!後,進入
printStr()開始解析驗證碼圖片。
解析的基本思想是:亮度處理、二值化、pytesser的image_to_string函式轉字串。
如果執行被註釋的這兩行程式碼
#imgry.save('g'+picname)
#out.save('b'+picname)
我們可以看到處理中的效果。就是去噪點調節對比度什麼的,和PS的原理是一樣的。
讓圖片更加清晰容易辨認而已。
然後經過
text = image_to_string(out)後,涉及到了三個字串處理函式。
#識別 text = text.strip() text = text.upper() text = text.replace(' ','')【strip函式】
s.strip(rm) 刪除s字串中開頭、結尾處,位於 rm刪除序列的字元
當rm為空時,預設刪除空白符
【upper函式】
轉成大寫字母
【replace函式】
去除字串中間的空格
最後執行print text後能夠輸出識別出來的字串。
經過多次測試驗證,我們發現只有非常容易辨認,或者說對比度比較大的圖片,才能夠準確辨認。
所以,該方法只適用於簡單驗證碼的識別。