python驗證碼簡單識別


因為需求,所以接觸了驗證碼這一塊,原本感覺到會很難,學了之后挺簡單的,但后來又發現自己還是too young。。。

PIL(python Image Library)

目前PIL的官方最新版本為1.1.7,支持的版本為python 2.5, 2.6, 2.7, 
PIL官方網站:http://www.pythonware.com/products/pil/ 
不支持python3,但有高手把它重新編譯生成python3下可安裝的exe了。這一非官方下載地址 http://www.lfd.uci.edu/~gohlke/pythonlibs/#pil , 
,它已經多年未更新了,差不多已經被遺棄了。

pillow

Pillow是PIL的一個派生分支,但如今已經發展成為比PIL本身更具活力的圖像處理庫。pillow可以說已經取代了PIL,將其封裝成python的庫(pip即可安裝),且支持python2和python3,目前最新版本是3.0.0。

Pillow的Github主頁:https://github.com/python-pillow/Pillow 
Pillow的文檔(對應版本v3.0.0): 
https://pillow.readthedocs.org/en/latest/handbook/index.html

安裝它很簡單 pip install pillow

使用方式:

#python2 
import Image 
#python3(因為是派生的PIL庫,所以要導入PIL中的Image) 
from PIL import Image

以python3為例,

  • open
from PIL import Image im = Image.open("1.png") im.show()
  • format

format屬性定義了圖像的格式,如果圖像不是從文件打開的,那么該屬性值為None;size屬性是一個tuple,表示圖像的寬和高(單位為像素);mode屬性為表示圖像的模式,常用的模式為:L為灰度圖,RGB為真彩色,CMYK為pre-press圖像。如果文件不能打開,則拋出IOError異常。

print(im.format, im.size, im.mode)
  • save
im.save("c:\\")
  • convert()

convert() 是圖像實例對象的一個方法,接受一個 mode 參數,用以指定一種色彩模式,mode 的取值可以是如下幾種: 
· 1 (1-bit pixels, black and white, stored with one pixel per byte) 
· L (8-bit pixels, black and white) 
· P (8-bit pixels, mapped to any other mode using a colour palette) 
· RGB (3x8-bit pixels, true colour) 
· RGBA (4x8-bit pixels, true colour with transparency mask) 
· CMYK (4x8-bit pixels, colour separation) 
· YCbCr (3x8-bit pixels, colour video format) 
· I (32-bit signed integer pixels) 
· F (32-bit floating point pixels)

im = Image.open('1.png').convert('L')
  • Filter

from PIL import Image, ImageFilter 
im = Image.open(‘1.png’) 
# 高斯模糊 
im.filter(ImageFilter.GaussianBlur) 
# 普通模糊 
im.filter(ImageFilter.BLUR) 
# 邊緣增強 
im.filter(ImageFilter.EDGE_ENHANCE) 
# 找到邊緣 
im.filter(ImageFilter.FIND_EDGES) 
# 浮雕 
im.filter(ImageFilter.EMBOSS) 
# 輪廓 
im.filter(ImageFilter.CONTOUR) 
# 銳化 
im.filter(ImageFilter.SHARPEN) 
# 平滑 
im.filter(ImageFilter.SMOOTH) 
# 細節 
im.filter(ImageFilter.DETAIL)

  • 查看圖像直方圖

    im.histogram()

  • 轉換圖像文件格式

def img2jpg(imgFile): if type(imgFile)==str and imgFile.endswith(('.bmp', '.gif', '.png')): with Image.open(imgFile) as im: im.convert('RGB').save(imgFile[:-3]+'jpg') 

 

 

 img2jpg('1.gif') img2jpg('1.bmp') img2jpg('1.png')
  • 屏幕截圖

    from PIL import ImageGrab 
    im = ImageGrab.grab((0,0,800,200)) #截取屏幕指定區域的圖像 
    im = ImageGrab.grab() #不帶參數表示全屏幕截圖

  • 圖像裁剪與粘貼

    box = (120, 194, 220, 294) #定義裁剪區域 
    region = im.crop(box) #裁剪 
    region = region.transpose(Image.ROTATE_180) 
    im.paste(region,box) #粘貼

  • 圖像縮放

    im = im.resize((100,100)) #參數表示圖像的新尺寸,分別表示寬度和高度

  • 圖像對比度增強

from PIL import Image  
from PIL import ImageEnhance  

#原始圖像 image = Image.open('lena.jpg') image.show() #亮度增強 enh_bri = ImageEnhance.Brightness(image) brightness = 1.5 image_brightened = enh_bri.enhance(brightness) image_brightened.show() #色度增強 enh_col = ImageEnhance.Color(image) color = 1.5 image_colored = enh_col.enhance(color) image_colored.show() #對比度增強 enh_con = ImageEnhance.Contrast(image) contrast = 1.5 image_contrasted = enh_con.enhance(contrast) image_contrasted.show() #銳度增強 enh_sha = ImageEnhance.Sharpness(image) sharpness = 3.0 image_sharped = enh_sha.enhance(sharpness) image_sharped.show() 

pytesseract

Python-tesseract是一款用於光學字符識別(OCR)的python工具,即從圖片中識別出其中嵌入的文字。Python-tesseract是對Google Tesseract-OCR的一層封裝。它也同時可以單獨作為對tesseract引擎的調用腳本,支持使用PIL庫(Python Imaging Library)讀取的各種圖片文件類型,包括jpeg、png、gif、bmp、tiff和其他格式,。作為腳本使用它將打印出識別出的文字而非寫入到文件。所以安裝pytesseract前要先安裝PIL(也就是現在的pillow)和tesseract-orc這倆依賴庫

tesseract-ocr是谷歌的開源項目,用於圖像文本識別,具體安裝使用情況可以參照圖片文字OCR識別-tesseract-ocr4.00.00安裝使用(4.000版本是實驗版,建議使用正式版的3.X)

這里寫圖片描述 
pytesseract是調用tesseract的一個庫,所以必須先安裝好tesseract, 
如何安裝pytesseract

pip install pytesseract

如何使用pytesseract

from PIL import Image 
import pytesseract 
print(pytesseract.image_to_string(Image.open('test.png'))) 
print(pytesseract.image_to_string(Image.open('test-european.jpg'), lang='fra'))
#后面的lang是語言的意思,fra是法語的意思.

很簡單,pytesseract只有一個簡單的image_to_string方法。

示例 
圖片:這里寫圖片描述

from PIL import Image
from PIL import ImageEnhance
import pytesseract
im=Image.open("1.jpg") im=im.convert('L') im.show() im=ImageEnhance.Contrast(im) im=im.enhance(3) im.show() print(pytesseract.image_to_string(im))

結果: 
圖一:這里寫圖片描述 
圖二:這里寫圖片描述

打印結果: 
這里寫圖片描述

打碼平台

眾所周知,上面的驗證碼識別都是小兒科,也就簡單的上面可以去去噪,換換灰度什么的,要是碰到了神奇的干擾線,或者奇葩的字母組合,那就基本上歇菜了,目前的驗證碼識別依舊存在着巨大的問題,所以打碼平台也就經久不衰了,這么多年過去了,非但沒有就此陌去,反而得到了飛速的發展,其中幾個比較有名,下次有時間再來補充。。。

——來補充了——— 
這次選擇的是雲打碼平台(非廣告),當然啦,只是本人選擇的是雲打碼,事實上其他的打碼平台都是類似的, 
首先要分清楚雲打碼平台的賬戶種類 
雲打碼平台分兩種:用戶和開發者 
我們只需使用用戶就可以了

注冊完之后可以選擇充值,先充1塊錢,有2000積分,下面是使用積分的說明:

這里寫圖片描述

也就是說1塊錢大概可以使用50次以上,這還是可以接受的

接下來就簡單多了 
用戶username: …….. 
密碼password: ……… 
賬戶余額balance:………..分

只需修改驗證碼地址和驗證碼種類,填好注冊時的用戶名和密碼,然后運行即可輸出相關信息,目測新浪微博驗證碼識別率95%以上

直接運行下面的源碼即可(記得改好上面的要求)


import http.client, mimetypes, urllib, json, time, requests ###################################################################### #驗證碼地址**(記得修改)** Image="C:\\Users\\Desktop\\ORC\\1.png" #驗證碼種類**(記得修改)** Species=1005 class YDMHttp: apiurl = 'http://api.yundama.com/api.php' username = '' password = '' appid = '' appkey = '' def __init__(self, username, password, appid, appkey): self.username = username self.password = password self.appid = str(appid) self.appkey = appkey def request(self, fields, files=[]): response = self.post_url(self.apiurl, fields, files) response = json.loads(response) return response def balance(self): data = {'method': 'balance', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey} response = self.request(data) if (response): if (response['ret'] and response['ret'] < 0): return response['ret'] else: return response['balance'] else: return -9001 def login(self): data = {'method': 'login', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey} response = self.request(data) if (response): if (response['ret'] and response['ret'] < 0): return response['ret'] else: return response['uid'] else: return -9001 def upload(self, filename, codetype, timeout): data = {'method': 'upload', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'codetype': str(codetype), 'timeout': str(timeout)} file = {'file': filename} response = self.request(data, file) if (response): if (response['ret'] and response['ret'] < 0): return response['ret'] else: return response['cid'] else: return -9001 def result(self, cid): data = {'method': 'result', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'cid': str(cid)} response = self.request(data) return response and response['text'] or '' def decode(self, filename, codetype, timeout): cid = self.upload(filename, codetype, timeout) if (cid > 0): for i in range(0, timeout): result = self.result(cid) if (result != ''): return cid, result else: time.sleep(1) return -3003, '' else: return cid, '' def post_url(self, url, fields, files=[]): for key in files: files[key] = open(files[key], 'rb'); res = requests.post(url, files=files, data=fields) return res.text ###################################################################### # 用戶名(填自己的)**(記得修改)** username = '*************' # 密碼(填自己的)**(記得修改)** password = '*******' # 軟件ID,開發者分成必要參數。登錄開發者后台【我的軟件】獲得!(非開發者不用管) appid = 1 # 軟件密鑰,開發者分成必要參數。登錄開發者后台【我的軟件】獲得!(非開發者不用管) appkey = '22cc5376925e9387a23cf797cb9ba745' # 圖片文件 filename = Image # 驗證碼類型,# 例:1004表示4位字母數字,不同類型收費不同。請准確填寫,否則影響識別率。在此查詢所有類型 http://www.yundama.com/price.html codetype = Species # 超時時間,秒 timeout = 60 # 檢查 if (username == 'username'): print('請設置好相關參數再測試') else: # 初始化 yundama = YDMHttp(username, password, appid, appkey) # 登陸雲打碼 uid = yundama.login(); print('uid: %s' % uid) # 查詢余額 balance = yundama.balance(); print('balance: %s' % balance) # 開始識別,圖片路徑,驗證碼類型ID,超時時間(秒),識別結果 cid, result = yundama.decode(filename, codetype, timeout); print('cid: %s, result: %s' % (cid, result)) ###################################################################### 

 

附贈幾張新浪微博的驗證碼: 
這里寫圖片描述

這里寫圖片描述

這里寫圖片描述

這里寫圖片描述

小結

驗證碼是一個神奇的產物,它充分的遏制住了一大批計算機上網的沖動,就是這么一個小小的驗證碼阻擋住了千軍萬馬,但是我相信未來的算法一定會將這個產物解決掉的-。-。-。-。-。-。-。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM