您好,登錄后才能下訂單哦!
這篇文章給大家介紹Python+Selenium+Pytesseract怎么實現(xiàn)圖片驗證碼識別,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
import json from io import BytesIO import time from test.testBefore.testDriver import driver from test.util.test_pytesseract import recognize from PIL import Image import allure import unittest ''' /處理驗證碼 ''' # 要截圖的元素 element = driver.find_element_by_xpath('//*[@id="imgVerifyCode"]') # 坐標 x, y = element.location.values() # 寬高 h, w = element.size.values() # 把截圖以二進制形式的數(shù)據(jù)返回 image_data = driver.get_screenshot_as_png() # 以新圖片打開返回的數(shù)據(jù) screenshot = Image.open(BytesIO(image_data)) # 對截圖進行裁剪 result = screenshot.crop((x, y, x + w, y + h)) # 顯示圖片 # result.show() # 保存驗證碼圖片 result.save('VerifyCode.png') # 調(diào)用recognize方法識別驗證碼 code = recognize('VerifyCode.png') # 輸入驗證碼 driver.find_element_by_xpath('//*[@id="txtcode"]').send_keys(code) ''' 處理驗證碼/ '''
注意:driver是引用我自己寫的文件,可以自己隨便寫一個。識別圖片的代碼單獨放在util文件夾下面的,參考標題三的代碼,需要時引用。以上代碼定位元素都需要根據(jù)自己的項目定位元素修改。
如果沒有輸出,又不確定你的pytesseract環(huán)境是否安裝好,可以用一張沒有干擾的圖片識別看看能不能有輸出結(jié)果,以下樣例在我的環(huán)境中可以直接輸出識別結(jié)果8fnp
直接使用pytesseract識別圖片
001.png
text = pytesseract.image_to_string('./001.png') print(text)
直接截圖的驗證碼圖片存在噪點或者干擾線等,直接使用pytesseract識別可能會沒有輸出結(jié)果,如果環(huán)境正常,但沒有輸出結(jié)果,那多半是因為圖片沒有處理好,識別不出來,可以多嘗試一些處理圖片的方式,以下代碼處理我截圖這種類似的圖片效果比較好。
對圖片處理的過程:
圖片處理過程中可以多用im.show()看看每一步處理后的圖片是不是符合預期,如果效果不好調(diào)一下參數(shù)。另外在學習過程中發(fā)現(xiàn)有童鞋說識別不出來把圖片使用cv2.resize()這個方法放大就能識別,可以參考Python中圖像的縮放 resize()函數(shù)的應用
實際截取的圖片
處理后的圖片
test_pytesseract.py
import pytesseract from fnmatch import fnmatch import cv2 import os def clear_border(img, img_name): ''' 去除邊框 ''' h, w = img.shape[:2] for y in range(0, w): for x in range(0, h): # if y ==0 or y == w -1 or y == w - 2: if y < 2 or y > w - 2: img[x, y] = 255 # if x == 0 or x == h - 1 or x == h - 2: if x < 1 or x > h - 1: img[x, y] = 255 return img def interference_line(img, img_name): ''' 干擾線降噪 ''' h, w = img.shape[:2] # ?。?!opencv矩陣點是反的 # img[1,2] 1:圖片的高度,2:圖片的寬度 for r in range(0, 2): for y in range(1, w - 1): for x in range(1, h - 1): count = 0 if img[x, y - 1] > 245: count = count + 1 if img[x, y + 1] > 245: count = count + 1 if img[x - 1, y] > 245: count = count + 1 if img[x + 1, y] > 245: count = count + 1 if count > 2: img[x, y] = 255 return img def interference_point(img, img_name, x=0, y=0): """點降噪 9鄰域框,以當前點為中心的田字框,黑點個數(shù) :param x: :param y: :return: """ # todo 判斷圖片的長寬度下限 cur_pixel = img[x, y] # 當前像素點的值 height, width = img.shape[:2] for y in range(0, width - 1): for x in range(0, height - 1): if y == 0: # 第一行 if x == 0: # 左上頂點,4鄰域 # 中心點旁邊3個點 sum = int(cur_pixel) \ + int(img[x, y + 1]) \ + int(img[x + 1, y]) \ + int(img[x + 1, y + 1]) if sum <= 2 * 245: img[x, y] = 0 elif x == height - 1: # 右上頂點 sum = int(cur_pixel) \ + int(img[x, y + 1]) \ + int(img[x - 1, y]) \ + int(img[x - 1, y + 1]) if sum <= 2 * 245: img[x, y] = 0 else: # 最上非頂點,6鄰域 sum = int(img[x - 1, y]) \ + int(img[x - 1, y + 1]) \ + int(cur_pixel) \ + int(img[x, y + 1]) \ + int(img[x + 1, y]) \ + int(img[x + 1, y + 1]) if sum <= 3 * 245: img[x, y] = 0 elif y == width - 1: # 最下面一行 if x == 0: # 左下頂點 # 中心點旁邊3個點 sum = int(cur_pixel) \ + int(img[x + 1, y]) \ + int(img[x + 1, y - 1]) \ + int(img[x, y - 1]) if sum <= 2 * 245: img[x, y] = 0 elif x == height - 1: # 右下頂點 sum = int(cur_pixel) \ + int(img[x, y - 1]) \ + int(img[x - 1, y]) \ + int(img[x - 1, y - 1]) if sum <= 2 * 245: img[x, y] = 0 else: # 最下非頂點,6鄰域 sum = int(cur_pixel) \ + int(img[x - 1, y]) \ + int(img[x + 1, y]) \ + int(img[x, y - 1]) \ + int(img[x - 1, y - 1]) \ + int(img[x + 1, y - 1]) if sum <= 3 * 245: img[x, y] = 0 else: # y不在邊界 if x == 0: # 左邊非頂點 sum = int(img[x, y - 1]) \ + int(cur_pixel) \ + int(img[x, y + 1]) \ + int(img[x + 1, y - 1]) \ + int(img[x + 1, y]) \ + int(img[x + 1, y + 1]) if sum <= 3 * 245: img[x, y] = 0 elif x == height - 1: # 右邊非頂點 sum = int(img[x, y - 1]) \ + int(cur_pixel) \ + int(img[x, y + 1]) \ + int(img[x - 1, y - 1]) \ + int(img[x - 1, y]) \ + int(img[x - 1, y + 1]) if sum <= 3 * 245: img[x, y] = 0 else: # 具備9領域條件的 sum = int(img[x - 1, y - 1]) \ + int(img[x - 1, y]) \ + int(img[x - 1, y + 1]) \ + int(img[x, y - 1]) \ + int(cur_pixel) \ + int(img[x, y + 1]) \ + int(img[x + 1, y - 1]) \ + int(img[x + 1, y]) \ + int(img[x + 1, y + 1]) if sum <= 4 * 245: img[x, y] = 0 return img def _get_dynamic_binary_image(filedir, img_name): ''' 自適應閥值二值化 ''' filename = './' + img_name.split('.')[0] + '-binary.png' img_name = filedir + '/' + filename im = cv2.imread(img_name) im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) th2 = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 1) return th2 def recognize(image): filedir = './' # 驗證碼路徑 for file in os.listdir(filedir): if fnmatch(file, image): img_name = file # 自適應閾值二值化 im = _get_dynamic_binary_image(filedir, img_name) # # 去除邊框 im = clear_border(im, img_name) # 對圖片進行干擾線降噪 im = interference_line(im, img_name) # 對圖片進行點降噪 im = interference_point(im, img_name) filename = './' + img_name.split('.')[0] + '-interferencePoint.png' # easy_code為保存路徑 cv2.imwrite(filename, im) # 保存圖片 text = pytesseract.image_to_string(im, lang="eng", config='--psm 6 digits') # config=digits只識別數(shù)字 return text ''' --psm 參數(shù)含義 0:定向腳本監(jiān)測(OSD) 1: 使用OSD自動分頁 2 :自動分頁,但是不使用OSD或OCR(Optical Character Recognition,光學字符識別) 3 :全自動分頁,但是沒有使用OSD(默認) 4 :假設可變大小的一個文本列。 5 :假設垂直對齊文本的單個統(tǒng)一塊。 6 :假設一個統(tǒng)一的文本塊。 7 :將圖像視為單個文本行。 8 :將圖像視為單個詞。 9 :將圖像視為圓中的單個詞。 10 :將圖像視為單個字符。 '''
關于Python+Selenium+Pytesseract怎么實現(xiàn)圖片驗證碼識別就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。