基於pytesseract的簡單驗證碼識別

今天我們談談簡單驗證碼的識別工作,這裡說的簡單驗證碼是這樣的:

驗證碼

說是簡單驗證碼其實在網站驗證中使用十分廣泛,經常會出現。

一般來說驗證碼在網頁中是以圖片的形式顯示出來, 在網頁源碼可能存在於以下幾種方式:

  1. 是在html語句中直接放入編碼後的驗證碼信息
  2. 是在html語句中直接放入請求的驗證碼url信息

針對第1種來說,普遍的使用base64進行編碼。

名詞解釋

正式講解前簡單做一下名詞解釋:

  • 驗證碼

是一種區分用戶是計算機還是人的公共全自動程序。可以防止:惡意破解密碼、刷票、論壇灌水,有效防止某個黑客對某一個特定註冊用戶用特定程序暴力破解方式進行不斷的登陸嘗試,實際上用驗證碼是現在很多網站通行的方式,我們利用比較簡易的方式實現了這個功能。這個問題可以由計算機生成並評判,但是必須只有人類才能解答。由於計算機無法解答驗證碼的問題,所以回答出問題的用戶就可以被認為是人類(百度百科)。

  • base64

Base64是網路上最常見的用於傳輸8Bit位元組碼的編碼方式之一,Base64就是一種基於64個可列印字元來表示二進位數據的方法。Base64編碼是從二進位到字元的過程,可用於在HTTP環境下傳遞較長的標識信息。例如採用了Base64來將一個較長的唯一標識符(一般為128-bit的UUID)編碼為一個字元串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進位數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base64編碼具有不可讀性,需要解碼後才能閱讀(百度百科)。

  • OCR

是指電子設備(例如掃描儀或數碼相機)檢查紙上列印的字元,通過檢測暗、亮的模式確定其形狀,然後用字元識別方法將形狀翻譯成計算機文字的過程。

  • 方式1/2的區別

我隨便找了兩個網址,通過firefox對其訪問過程進行了查看,對於第1種的訪問過程是這樣的:

對於第2種的訪問過程是這樣的:

通常我們在客戶端顯示隨機驗證碼圖片的時候是通過<img src="url"/>這個標籤來顯示的驗證碼圖片。這個url就是隨機驗證碼的圖片。當網頁將網站源碼載入完成後,會再次通過這個url地址請求伺服器,加重伺服器負擔(方式2)

然而<img src=」data:image/jpg;base64,imgcode...」>也可以顯示圖片的,需要做的就是將圖片重新按base64格式進行編碼。這樣就不會再次發送一次HTTP請求,而是讓客戶端瀏覽器解析base64的代碼(方式1)。

通過對比兩張圖可以發現,方式2確實是多了一次HTTP請求。

相關技術

驗證碼的解析我們這裡用到的Python第三方庫有requestsPillowpytesseract以及Tesseract-OCR引擎

  • requests:一個簡單易用的Python HTTP訪問庫,總之很強大。
  • Pillow:Python里的圖像處理庫(PIL:Python Image Library),提供了廣泛的文件格式支持,強大的圖像處理能力,主要包括圖像儲存、圖像顯示、格式轉換以及基本的圖像處理操作等。
  • pytesseract:google的Tesseract-OCR引擎的一個python封裝包,用於python的光學字元識別(OCR)工具。 它可以識別和「讀取」圖像中嵌入的文本。
  • Tesseract-OCR引擎:開源的OCR識別引擎,初期Tesseract引擎由HP實驗室研發,後來貢獻給了開源軟體業,後經由Google進行改進,消除bug,優化,重新發布。項目地址為:tesseract-ocr

這裡Pillow和pytesseract可以通過pip安裝,Tesseract-OCR引擎需要下載exe文件安裝,關注微信公眾號:學點編程吧,發送:teocr,即可獲得下載鏈接。

url或base64編碼轉成圖片

驗證碼解析,首先要有驗證碼才行,這個必須是圖片啊。但是我們看網頁源碼都是一長串的編碼或者是url鏈接,這個該怎麼辦呢?類似這種的。

所以我們識別驗證碼的第一就是得到驗證碼圖片,具體的代碼如下:

import codecs, requests#使用codes打開文件可以指定具體的編碼nfrom lxml import etree#lxml是以Python語言處理XML和HTML的功能的庫。nfrom io import BytesIO#操作二進位文件nfrom PIL import Image#圖形處理的庫nnwith codecs.open("code.html","r","utf-8") as f:n html = f.read()ntree = etree.HTML(html)#因為我們通過read()函數讀取字元串,但是我們需要使用HTML文檔,通過etree.HTML將得到的字元串進行HTML解析。nimg_data = tree.xpath("//@src")n#對得到HTML文本進行xpath,找到驗證碼的具體內容。n#詳細xpath的使用可以參考這篇文章:XPath 與 lxml - CSDN博客 是一門在 XML 文檔中查找信息的語言。n# XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。XPath 是 W3C XSLT 標準的主要元素,並且 XQuery 和 XPointer 都構建於 XPath 表達之上。n# 詳細可見:XPath 教程nimg_data1 = img_data[0].partition(,)[-1]#得到的字元串按照,進行分割成列表,取最後一個,也就是base64編碼nbinary_img_data1 = img_data1.decode(base64)#base64解碼nfile_img1 = BytesIO(binary_img_data1)#對得到的二進位數據進行操作nimg1 = Image.open(file_img1)nimg1.save(img1.png)#保存驗證碼#url的驗證碼解析nresponse = requests.get(img_data[1])#訪問具體的驗證碼urlnfile_img2 = BytesIO(response.content)#對得到的二進位數據進行操作nimg2 = Image.open(file_img2)nimg2.save(img2.png)#保存驗證碼n

圖片再處理

因為我們要使用OCR技術,為了使驗證碼圖片更易識別,我們需要對圖片進行一些處理。首先分析一下驗證碼圖片。我們打開Photoshop對驗證碼進行取色分析(如下圖),基本上可以得知背景色的RGB數值一般大於140,具體的驗證碼RGB數值一般都會小於這個數值,當然這個數值你可以根據自己觀察的情況進行調整,只要符合你的要求就行。

所以我們形成了如下代碼:

gray = img2.convert(L)n#圖像對象轉化(L:8位像素,表示黑和白)n#可以參考:Python圖像處理庫PIL的基本概念介紹 - icamera0的博客 - CSDN博客nbw = gray.point(lambda x:0 if x<140 else 255,1)#如果RGB數值小於140的變成1,否則是255。也就是將驗證碼背景變成白色,具體字元變成黑色。nbw.save(aa.png)n

效果如下:

讀取驗證碼

使用pytesseract對驗證碼進行讀取

vcode = pytesseract.image_to_string(bw).replace( , )nprint vcoden

因為驗證碼中有空格,但是這個在網站驗證中是不需要填入的,所以我們要去掉。

最終效果如下:

總結

今天介紹了簡單的驗證碼識別,主要涉及到Pillowpytesseract這兩個庫的使用。以後有時間再談談複雜驗證碼的識別。

今天的代碼和相關測試網頁,關注微信公眾號:學點編程吧,發送:驗證碼,即可獲得下載鏈接。


推薦閱讀:

Python入門 面向對象編程基礎
Python入門到精通視頻課程(5)
Python 繪製分形圖(曼德勃羅集、分形樹葉、科赫曲線、分形龍、謝爾賓斯基三角等)附代碼
人生若只如初見,何必找包爬數據
Python面向對象編程從零開始(4)—— 小姐姐請客下篇

TAG:Python | Python库 | Python教程 |