在Python爬蟲過程中,有些網站需要驗證碼通過后方可進入網頁,目的很簡單,就是區分是人閱讀訪問還是機器爬蟲。驗證碼問題看似簡單,想做到准確率很高,也是一件不容易的事情。為了更好學習爬蟲,后續推文中將會更多介紹爬蟲問題的解決方案。本篇推文將分享三種解決驗證碼的方法,如果你有比較好的方案,歡迎留言區討論交流,共同進步。
1.pytesseract
很多人學習python,不知道從何學起。
很多人學習python,掌握了基本語法過后,不知道在哪里尋找案例上手。
很多已經做案例的人,卻不知道如何去學習更加高深的知識。
pytesseract是google做的ocr庫,可以識別圖片中的文字,一般用在爬蟲登錄時驗證碼的識別,在安裝pytesseract環境過程中會遇到各種坑的事情,如果你需要安裝,可以按照如下流程去做,避免踩坑。下面以 mac為例。
1.安裝方法
pip install pytesseract
2.此外,還需安裝Tesseract,它是一個開源的OCR引擎,能識別100多種語言。
brew install tesseract
3.查看安裝位置為
brew list tesseract
/usr/local/Cellar/tesseract/4.1.1/bin/tesseract
/usr/local/Cellar/tesseract/4.1.1/include/tesseract/ (19 files)
/usr/local/Cellar/tesseract/4.1.1/lib/libtesseract.4.dylib
/usr/local/Cellar/tesseract/4.1.1/lib/pkgconfig/tesseract.pc
/usr/local/Cellar/tesseract/4.1.1/lib/ (2 other files)
/usr/local/Cellar/tesseract/4.1.1/share/tessdata/ (35 files)
4.配置環境變量
export TESSDATA_PREFIX=/usr/local/Cellar/tesseract/4.1.1/share/tessdata
export PATH=$PATH:$TESSDATA_PREFIX
5.如何出現如下報錯
'TesseractNotFoundError: tesseract is not installed or it's not in your PATH'
6.修改pytesseract.py的cmd
'tesseract_cmd = '/usr/local/Cellar/tesseract/4.1.1/bin/tesseract''
先驗證一個簡單的驗證碼
代碼如下
from PIL import Image,ImageFilter
import pytesseract
path ='/Users/****/***.jpg'
captcha = Image.open(path)
result = pytesseract.image_to_string(captcha)
print(result)
結果輸出
51188
再換一張試一下
輸入代碼后,結果錯誤輸出為
1364
由此看出,pytesseract對於簡單方法有效,並不像有些人寫的這么好,當然可以通過灰度、二值等方法,效果並不是很理想,稍微復雜的需要尋找其他解決方案,如果解決上述問題呢,我們看下面的解決方案。
2.百度OCR接口
調用百度OCR接口(代碼示例)
# encoding:utf-8
import requests
import base64
'''
通用文字識別(高精度版)
'''
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic"
# 二進制方式打開圖片文件
f = open('[本地文件]', 'rb')
img = base64.b64encode(f.read())
params = {"image":img}
access_token = '[調用鑒權接口獲取的token]'
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
print (response.json())
上述方案沒解決的問題,調用此方法試一下,可以順利解決。
7364
那么對於更復雜的驗證碼呢?
首先直接調用結果輸出
Ygax6-
結果把干擾線識別出來Y和-,可以看出百度OCR接口對復雜驗證碼能識別,但是對干擾線的問題,無法解決。如何解決上述問題呢?對於復雜的驗證碼,我們是不能直接調用,我們先做一些預處理:灰度、二值化等。
再次調用接口
gax6
上述問題得到了解決。對於超級變態的驗證碼如何解決呢?幾個0?幾個O?下面提供一種深度學習解決方案。
3.深度學習
深度學習驗證碼識別可能並不適合所有人,原因很簡單,首先不是每個人都有算法基礎。其次小編親自測試來一下,cpu資源的消耗也非常高,如果你有雲端資源可以跑一下。深度學習的驗證碼識別,我這邊介紹一下解決方案的思路,目前企業級的驗證識別更為復雜。
1.搭建基於keras框架的深度學習模型
from keras.models import *
from keras.layers import *
input_tensor = Input((height, width, 3))
x = input_tensor
for i in range(4):
x = Convolution2D(32*2**i, 3, 3, activation='relu')(x)
x = Convolution2D(32*2**i, 3, 3, activation='relu')(x)
x = MaxPooling2D((2, 2))(x)
x = Flatten()(x)
x = Dropout(0.25)(x)
x = [Dense(n_class, activation='softmax', name='c%d'%(i+1))(x) for i in range(4)]
model = Model(input=input_tensor, output=x)
model.compile(loss='categorical_crossentropy',
optimizer='adadelta',
metrics=['accuracy'])
2.模型訓練
model.fit_generator(gen(), samples_per_epoch=51200, nb_epoch=5,
nb_worker=2, pickle_safe=True,
validation_data=gen(), nb_val_samples=1280)
3.測試模型
X, y = next(gen(1))
y_pred = model.predict(X)
plt.title('real: %s\npred:%s'%(decode(y), decode(y_pred)))
plt.imshow(X[0], cmap='gray')
4.結果展示
結論
驗證碼識別問題正如推文開頭所說,看似簡單,實際上遠比想象的要復雜的多。有些解決方案也可能是針對性解決方案。