Python識別圖形驗證碼實戰項目

一、前言

  前幾天有人問我的框架在登錄時支不支持用戶名、密碼以及驗證碼。我回答是不支持,因爲驗證碼是爲了防爬蟲的,自動化遇到有驗證碼可以叫開發去掉或者寫個萬能驗證碼,那同學給我的回答是開發不願意,只能自己搞。哈哈哈,怎麼說呢,工作中學會說服開發也是自己的一種能力呢。好的,下面開始研究識別圖形碼的案例了。

二、tesserocr

參考:https://juejin.cn/post/6844903618605219848

1、tesserocr介紹

tesserocr是Python的一個OCR識別庫,是google開源的OCR,但其實是對tesseract做了一層Python Api的封裝。

OCR,全稱叫 Optical Character Recognition,中文翻譯叫光學字符識別,是指通過掃描字符,通過其形狀將其翻譯成電子文本的過程;

舉例:當有一個圖形驗證碼,先使用OCR技術將其轉化成電子文本,然後爬蟲將識別的結果提交到服務器,便達到自動識別驗證碼的過程;

還有個疑問,之前有在圖形識別領域,還有個opencv的玩意,那這兩者有什麼區別?

答:opencv專注機器視覺,tesseract專注字符識別

所以從領域來說,opencv更廣,而圖形驗證碼,opencv也可以做,但殺雞焉用牛刀~

2、環境準備

本人電腦配置:win10,python3.8,下面講述的是在windows下的安裝

1)安裝tesseract

在Windows下,要先下載tesseract,它爲tesserocr提供了支持;
tesseract下載地址:https://digi.bib.uni-mannheim.de/tesseract/
其中文件名中帶有dev的爲開發版本,不帶dev則爲穩定版本,例如我這裏是下載 tesseract-ocr-w64-setup-v5.3.0.20221214.exe;

 下載後雙擊,一路點擊,直到出現下面這個頁面,這裏需要勾選紅框裏的Additional language data(download),這個選項是安裝OCR識別支持的語言包,這樣OCR就可以識別多國語言,然後再一路點擊NEXT即可,因爲要下載語言包,所以需要點時間,大概10-20分鐘左右,跟網速有關,如果不需要支持多國語言的話,也可以不勾選,自由選擇。默認包含英文字庫的

如何驗證tesseract是否安裝成功?直接cmd下輸入tesseract即可,成功會直接顯示信息:

 如果提示'tesseract' 不是內部或外部命令,則是因爲沒有配置環境變量,手動把tesseract根目錄配置到path參數下即可,這塊不詳細說明。

 到此爲止,tesseract安裝成功啦~

2)安裝tesserocr

接下來就安裝tesserocr了

方式一(不建議,一般安裝不成功),嘗試pip安裝:pip3 install tesserocr pillow

方式二:通過.whl文件安裝

下載地址:Releases · simonflueckiger/tesserocr-windows_build (github.com)

找到與tesseract對於版本的tesserocr(本人安裝的tesseract v5.3.0.20221214,所以選擇tesserocr-2.5.2-cp38-cp38-win_amd64.whl)

下載後,把下載下來的.whl文件放在任意路徑下 ,然後通過pip命令安裝該文件,舉例文件放在了D:\software\tesser。

安裝命令:pip install D:\software\tesser\tesserocr-2.5.2-cp38-cp38-win_amd64.whl

(這裏pip install後面跟着的是自己下載好的.whl文件即可,tips:可以把文件直接拖到cmd窗口去)

如果pycharm中導入後調用方法報錯,比如tesserocr._tesserocr.image_to_text報錯問題。

可以將Tesseract-OCR下的tessdata文件複製到你的Python安裝路徑下即可

 最終就安裝上tesserocr啦~

如何驗證是否真的安裝了?很簡單,直接import tesserocr,不報錯就說明安裝好了;

 

3、使用舉例

1)圖形驗證碼圖片如下:

2)代碼如下:

import tesserocr
from PIL import Image

#新建Image對象
image = Image.open("m.png")
#進行置灰處理
image = image.convert('L')
#這個是二值化閾值 150
threshold = 122
table = []

for i in  range(256):
    if i < threshold:
        table.append(0)
    else:
        table.append(1)
#通過表格轉換成二進制圖片,1的作用是白色,不然就全部黑色了
image = image.point(table,"1")
image.show()
result = tesserocr.image_to_text(image)
print("驗證碼:"+result)

3)執行效果如下:

三、ddddocr

1、ddddocr介紹

項目地址:https://github.com/sml2h3/ddddocr

2、環境準備

python版本>3.8

pip命令安裝:
方式一:pip install ddddocr
方式二:pip install ddddocr -i https://pypi.tuna.tsinghua.edu.cn/simple/

3、使用舉例

1)圖形驗證碼圖片如下:

 2)代碼如下:

import ddddocr

ocr = ddddocr.DdddOcr()
with open('m.png', 'rb') as f:
    img_bytes = f.read()
res = ocr.classification(img_bytes)
print('識別出的驗證碼爲:' + res)

3)執行後效果如下:

 

四、pytesseract

1、pytesseract介紹

pytesseract是google的tesseract的一個python版本的接口庫,想要真正使用,首先需要安裝tesseract

2、環境準備

安裝tesseract可以看第二大點,安裝成功後再安裝pytesseract,安裝命令:pip install pytesseract

3、使用舉例

1)圖形驗證碼如下:

 2)代碼如下:

import pytesseract
from PIL import Image
pic = Image.open('1.png')
imgry = pic.convert('L')
imgry.show()
threshold = 150
table = []
for i in range(256):
    if i < threshold:
        table.append(0)
    else:
        table.append(1)
out = imgry.point(table, '1')
out.show()
#pic 爲打開的圖片,lang指定識別轉換的語言庫
text = pytesseract.image_to_string(pic,lang='chi_sim')
print("驗證碼:"+text)

3)執行效果如下:

 五、完整項目案例

1、網站地址https://www.qb5.tw/login.php

  參考別人博客的,忘了博客地址了,這裏主要實現登錄時輸入賬號密碼以及驗證碼的場景。

2、用ddddocr進行識別,完整代碼如下

import requests
from lxml import etree
from requests.packages import urllib3
import ddddocr

urllib3.disable_warnings()

url = "https://www.qb5.tw/login.php"
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

# 1.創建session對象
session = requests.session()
pag_text = session.get(url=url, headers=headers).text

# 2.實例化一個etree對象,方便後面對頁面進行數據解析
tree = etree.HTML(pag_text)

# 3.提取驗證碼下載地址
img_path = "https://www.qb5.tw" + tree.xpath('//*[@id="main"]/div[1]/form/fieldset/p[3]/img/@src')[0]
print(img_path)

# 4.下載驗證碼,以二進制的方式進行保存
img_content = session.get(img_path, headers=headers, verify=False).content
with open('./img.png', 'wb') as f:
    f.write(img_content)
    print('驗證碼圖片下載成功')

#img_code = input('請輸入驗證碼:')
ocr = ddddocr.DdddOcr()
with open('img.png','rb') as f:
    img_bytes = f.read()
code = ocr.classification(img_bytes)
print("識別圖形驗證碼爲:"+code)

# 5.進行登錄,定義post的參數
data = {
    'username': 'test123',
    'password': 'admin@123',
    'checkcode': code,
    'usecookie': '315360000',
    'action': 'login',
    'submit': '立即登陸'
}
# 判斷是否登錄成功
response = session.post(url=url, data=data, headers=headers, verify=False)
response.encoding = 'gbk'  # 編碼防止亂碼
response_text = response.text
if "登錄成功" in response_text:
    print("登陸成功")
# 請求個人信息頁
ge = session.get(url='https://www.qb5.tw/userdetail.php', headers=headers, verify=False)
with open('xs.html', 'w', encoding='gbk') as f:
    f.write(ge.text)

3、執行效果如下

六、結束語

tesserocr也只是識別手段的一種,如果需要高精度的識別,可以嘗試TensorFlow實現深度學習模型,通過訓練模型來識別圖形驗證碼。

案例中的執行效果截圖都可以識別出驗證碼,那是因爲需要演示成功例子,實際上嘗試了3種開源的ocr,識別精度都很低,如果工作中實在有需要用到,建議用百度或阿里的ocr,不過需要收費額~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章