python + selenium獲取驗證碼


解決驗證碼的方法:

方法一:讓開發幫忙去掉驗證碼代碼,重新部署環境。(不推薦)

方法二:弄個萬能驗證碼,每次登陸都可以登陸。(不推薦)

方法三:用cookie添加登陸名和密碼避開驗證碼的方式。(我還不會)

方法四:老老實實獲取驗證碼。(重點講這個)

采用方法四需要引用第三方庫:pytesseract,該庫依賴於Tesseract,所以需要先安裝Tesseract。

1、安裝Tesseract模塊

     git文檔地址:https://digi.bib.uni-mannheim.de/tesseract/    

     請安裝不帶dev的穩定版,下載后就是一個exe安裝包,直接右擊安裝即可。

2、如果您想使用其他語言,請下載相應的培訓數據,直接下載整個zip文件,解壓后將文件復制到'tessdata'目錄中。C:\Program Files (x86)\Tesseract-OCR\tessdata

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)后面的處理過程與思路一的圖片處理方法相同。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM