廢話
目前許多網(wǎng)站出于安全和反爬的目的,在登錄界面,或一些關(guān)鍵操作的地方都設(shè)置了驗(yàn)證碼,這些驗(yàn)證碼的形式也是多種多樣的,有普通圖形驗(yàn)證碼、滑動(dòng)驗(yàn)證碼、點(diǎn)觸驗(yàn)證碼、宮格驗(yàn)證碼等,這些驗(yàn)證碼給爬蟲開發(fā)增加了難度,但也不是沒有辦法,這篇文章將介紹圖片驗(yàn)證碼的識(shí)別。
庫(kù)的安裝
圖形驗(yàn)證碼的識(shí)別需要安裝tesserocr。tesserocr是python的一個(gè)OCR識(shí)別庫(kù)。
什么是OCR
光學(xué)字符識(shí)別(英語:Optical Character Recognition,OCR)是指對(duì)文本資料的圖像文件進(jìn)行分析識(shí)別處理,獲取文字及版面信息的過程。
———— 維基百科
說白了就是將圖片中的字符根據(jù)其形狀翻譯成電子文本的過程
環(huán)境配置
tesserocr其實(shí)是對(duì)tesseract(google開源的OCR)做了一層PythonAPI封裝,核心還是tesseract,所以在安裝tesserocr之前,需要先安裝tesseract 也叫tesseract-ocr
sudo apt-get install -y tesseract-ocr libtesseract-dev libleptionica-dev
sudo pip3 install tesserocr pillow
使用方法
import tesserocr
from PIL import Image
# 方法1
image = Image.open('/home/yhch/Pictures/yzmtest.jpg')
result = tesserocr.image_to_text(image)
print('[method 1] 識(shí)別結(jié)果:',result)
# 方法2
result = tesserocr.file_to_text('/home/yhch/Pictures/yzmtest.jpg')
print('[method 2] 識(shí)別結(jié)果:',result)
識(shí)別的圖片yzmtest.jpg如下圖所示,是我從google首頁截的圖,看程序能否識(shí)別出單詞

識(shí)別結(jié)果如下:

1.方法1
通過PIL庫(kù),創(chuàng)建image對(duì)象,調(diào)用tesserocr的 image_to_text的方法,將圖片的內(nèi)容轉(zhuǎn)化為文字。
2.方法2
方法2是直接訪問文件對(duì)象。方法也較為簡(jiǎn)單。
驗(yàn)證碼處理(轉(zhuǎn)灰度,二值化)
大多數(shù)驗(yàn)證碼都會(huì)做一些防破解的處理,就像下面的圖片,驗(yàn)證碼上面有很多干擾的線條。

image = Image.open('/home/yhch/Pictures/test.aspx')
image.show()
result = tesserocr.image_to_text(image)
print('識(shí)別結(jié)果:',result)
>>>
/usr/bin/python3 /home/yhch/PycharmProjects/python爬蟲/untitled/yanzhma.py
識(shí)別結(jié)果:
識(shí)別不出來,有的時(shí)候是識(shí)別不準(zhǔn)確,這時(shí)候我們需要對(duì)驗(yàn)證碼圖片進(jìn)一些處理。
灰度圖
灰度圖,Gray Scale Image 或是Grey Scale Image,又稱灰階圖。把白色與黑色之間按對(duì)數(shù)關(guān)系分為若干等級(jí),稱為灰度?;叶确譃?56階。轉(zhuǎn)灰度說白了就是將彩色圖轉(zhuǎn)為灰度圖。給image對(duì)象調(diào)用convert方法,傳入?yún)?shù)L,即可將圖片轉(zhuǎn)為灰度圖。
image = Image.open('/home/yhch/Pictures/test.aspx')
image.show()
image = image.convert('L')
image.show()

二值化
圖像二值化( Image Binarization)就是將圖像上的像素點(diǎn)的灰度值設(shè)置為0或255,也就是將整個(gè)圖像呈現(xiàn)出明顯的黑白效果的過程。
在數(shù)字圖像處理中,二值圖像占有非常重要的地位,圖像的二值化使圖像中數(shù)據(jù)量大為減少,從而能凸顯出目標(biāo)的輪廓。
前面我們已經(jīng)轉(zhuǎn)化為灰度圖,通過二值化將灰度的數(shù)值是在0~256之間調(diào)節(jié)(根據(jù)實(shí)際情況)。
import tesserocr
from PIL import Image
image = Image.open('/home/yhch/Pictures/test.aspx')
image.show()
image = image.convert('L')
image.show()
threshold = 80
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
image = image.point(table,'1')
image.show()
result = tesserocr.image_to_text(image)
print('[優(yōu)化]識(shí)別結(jié)果:',result)
通過表格轉(zhuǎn)換成二進(jìn)制圖片,append(0),繪制黑色,threshold 設(shè)置了一個(gè)臨界值,80是調(diào)出的合適值。

識(shí)別結(jié)果是準(zhǔn)確的,看圖可能你會(huì)感覺到,進(jìn)行處理完之后反倒不好識(shí)別,但對(duì)于計(jì)算機(jī)而言,如果你不進(jìn)行這樣的處理,是識(shí)別不出來的。
如果你對(duì)灰度圖尤其是二值化的閥值還是不太清楚,看下面
原圖

from PIL import Image
image = Image.open('/home/yhch/Pictures/test.jpg')
image = image.convert('L')
image.show()
threshold = 40
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
image = image.point(table,'1')
image.show()

就這里的代碼而言,閥值越小,append 1就越多,白色區(qū)域就越多;閥值越大,append 0就越多,黑色區(qū)域就越多。你只有找到一個(gè)準(zhǔn)確的值,才能人物輪廓清晰,計(jì)算機(jī)更好識(shí)別。
小結(jié)
通過對(duì)驗(yàn)證碼圖片進(jìn)行轉(zhuǎn)灰度處理,再通過合適的二值化閥值進(jìn)行二值化處理,得到字符輪廓清晰,易于識(shí)別的驗(yàn)證碼,再通過tesserocr包進(jìn)行OCR識(shí)別,后期配合爬蟲將識(shí)別出的驗(yàn)證碼提交到服務(wù)器,就可以對(duì)需要圖形驗(yàn)證后的才能進(jìn)入的頁面爬取了。
關(guān)于作者
個(gè)人博客 https://yhch.xyz;微信公眾號(hào):楊浩成。