解決驗證碼的方法:
方法一:讓開發幫忙去掉驗證碼代碼,重新部署環境。(不推薦)
方法二:弄個萬能驗證碼,每次登陸都可以登陸。(不推薦)
方法三:用cookie添加登陸名和密碼避開驗證碼的方式。(我還不會)
方法四:老老實實獲取驗證碼。(重點講這個)
采用方法四需要引用第三方庫:pytesseract,該庫依賴於Tesseract,所以需要先安裝Tesseract。
1、
git文檔地址:https://digi.bib.uni-mannheim.de/tesseract/
請安裝不帶dev的穩定版,下載后就是一個exe安裝包,直接右擊安裝即可。
2、
3、配置環境變量:
(1)編輯系統變量里面 path,添加下面的安裝路徑:C:\Program Files (x86)\Tesseract-OCR
(2)添加TESSDATA_PREFIX變量,值為:C:\Program Files (x86)\Tesseract-OCR\tessdata
cmd命令模式下測試是否安裝成功:
tesseract test.jpg text -l chi_sim
4、安裝python的第三方庫:
pip install pillow #一個python的圖像處理庫,pytesseract依賴
pip install pytesseract
5、找到pytesseract的安裝包,C:\Python34\Lib\site-packages\pytesseract,編輯pytesseract.py文件(此步驟必須做,否則運行代碼時會報錯):
tesseract_cmd = 'C:/Program Files (x86)/Tesseract-OCR/tesseract.exe'
獲取驗證碼有2種思路:
1、截圖登陸頁面,再截取驗證碼圖片,識別;
2、直接在登陸頁面,定位到驗證碼,將驗證碼圖片另存為,識別;
思路一具體實現過程:
(1)先計算瀏覽器與登陸頁面截圖的比例值,再計算對應的驗證碼圖片位置。不這樣做的話,會導致獲取的驗證碼位置不正確。
browser.maximize_window() #獲取瀏覽器大小 size_window = browser.get_window_size() time.sleep(1) #獲取截圖 browser.save_screenshot('login.png') login_img = Image.open('login.png') (login_width,login_height) = login_img.size logger.info('截圖的寬高:') logger.info(login_width,login_height) #計算瀏覽器與截圖比例 scale = size_window['width'] / login_width #獲取驗證碼 code_loc = browser.find_element_by_xpath('//*[@id="valiCode"]').location code_size = browser.find_element_by_xpath('//*[@id="valiCode"]').size #獲取驗證碼位置 #此處的X和Y分別加了數字,因為前端的樣式中,驗證碼標簽img的margin-left為15,margin-top為5 location_X = math.ceil(code_loc['x'] / scale) + 15 location_Y = math.ceil(code_loc['y'] / scale) + 5 location_height = math.ceil(code_size['height'] / scale) location_width = math.ceil(code_size['width'] / scale) code_img = login_img.crop((location_X,location_Y,location_X + location_width ,location_Y + location_height)) code_img.save('code.png')
(2)再將獲取到的驗證碼圖片,先進行二值化處理,以便提取驗證碼更容易,這里涉及一些圖像處理的算法。
#先二值化處理 image=Image.open(img) # 灰度圖 lim=image.convert('L') # 灰度閾值設為100,低於這個值的點全部填白色 threshold=100 table=[] for j in range(256): if j<threshold: table.append(0) else: table.append(1) bim=lim.point(table,'1') bim.save('newImg.png')
(3)處理后的圖像更容易獲取驗證碼,這里采用pytesseract庫轉化,注意后面的參數設置。
先前不設置參數時,總是將1轉化為7,設置后轉化的准確率杠杠滴。
當然,目前只是識別數字型的驗證碼,文字類型的方法應該是類似的。
lastpic = Image.open('newImg.png') text = pytesseract.image_to_string(lastpic,lang='eng',config='--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789').strip() #后面的配置簡直是神器啊,之前一直將1讀成7,加配置后很准確 with open('output.txt','w') as f: f.write(text) with open('output.txt','r') as f: code = f.read() f.close() logger.info("獲取的驗證碼為:") logger.info(code)
思路二具體實現過程:
(1)先定位到登陸頁面中驗證碼的位置,將驗證碼圖片另存到一個路徑下,並且返回最新時間保存的圖片。
# 把驗證碼另存為圖片 def image_save_as(): image = driver.find_element_by_id("valiCode") actions = ActionChains(driver) actions.context_click(image) actions.perform() pyautogui.typewrite(['down', 'down', 'enter', 'enter']) # 右鍵找到圖片另存為 sleep(2) pyautogui.typewrite(['enter']) sleep(2) def get_newest_image(image_path): lists = os.listdir(image_path) lists.sort(key=lambda fn:os.path.getmtime(image_path + "\\" + fn)) # 按時間排序 image_new = os.path.join(image_path, lists[-1]) return image_new
(2)后面的處理過程與思路一的圖片處理方法相同。