1. 程式人生 > >【詳解】簡單驗證碼的解析

【詳解】簡單驗證碼的解析

首先把大致思路說一下,解析驗證碼就是先獲取驗證碼圖片,然後通過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後能夠輸出識別出來的字串。

經過多次測試驗證,我們發現只有非常容易辨認,或者說對比度比較大的圖片,才能夠準確辨認。

所以,該方法只適用於簡單驗證碼的識別。