1. 程式人生 > >Selenium利用Python影象識別解決驗證碼問題

Selenium利用Python影象識別解決驗證碼問題

Python影象識別參考:http://www.th7.cn/Program/Python/201602/768304.shtml

指令碼思路:瀏覽器頁面到達驗證碼輸入頁面,針對驗證碼圖片進行另存為儲存到本地,然後將圖片複製到pytesser資料夾下(只有指令碼和圖片都在該資料夾下才能完成識別),然後呼叫Python圖片識別處理驗證碼圖片函式並返回驗證碼,然後就可以完成驗證碼輸入操作!

運用到的模組:python圖片識別、Python模擬鍵盤、Selenium滑鼠事件

第一步:在C:\Python27\Lib\site-packages\pytesser路徑下建立該Python檔案,用作圖片識別的方法

#coding=utf-8
'''
Created on 2018年4月22日

@author: Administrator
'''
from selenium import webdriver
import time,shutil,random,os
from selenium.webdriver.common.action_chains import ActionChains
import win32api,win32con
from PIL import Image
from io import BytesIO
from pytesser import *


def identifyImage(driver,element,imageName,browserPath='C:\\Users\\Administrator\\Downloads',pytesserPath='C:\\Python27\\Lib\\site-packages\\pytesser'):
    '''
    element:圖片驗證碼元素;
    imageName:儲存的驗證碼圖片名稱;
    browserPath:瀏覽器預設下載路徑;
    pytesserPath:pytesser資料夾路徑;
    DownloadPath:圖片驗證碼另存為完成的檔案路徑(包含檔名);
    savePath:圖片驗證碼儲存在pytesser中的路徑(包含檔名);
    '''
    DownloadPath = browserPath + '\\' + imageName
    savePath = pytesserPath + '\\' + imageName
    try:
        os.remove(DownloadPath)
    except WindowsError:
        pass
    try:
        os.remove(savePath)
    except WindowsError:
        pass
    action = ActionChains(driver)
    action.context_click(element).perform()
    win32api.keybd_event(86,0,0,0)
    win32api.keybd_event(86,0,win32con.KEYEVENTF_KEYUP,0)
    time.sleep(2)
    win32api.keybd_event(13,0,0,0)
    win32api.keybd_event(13,0,win32con.KEYEVENTF_KEYUP,0)
    time.sleep(2)
    shutil.copy(DownloadPath,pytesserPath)
    im = Image.open(savePath)
    imagetext = image_to_string(im).strip()
    return imagetext

第二步:實際場景呼叫圖片識別

#coding=utf-8
'''
Created on 2018年4月22日

@author: Administrator
'''
from selenium import webdriver
import time,shutil,random,os
from selenium.webdriver.common.action_chains import ActionChains
import win32api,win32con
from pytesser.IdentifyImage import identifyImage
from PIL import Image
from io import BytesIO
from pytesser import *


def login(username=u'XXXXXX',password=u'XXXXXX'):   #登入函式
    driver= webdriver.Chrome()
    driver.maximize_window()
    driver.get('XXXXXX') 
    driver.implicitly_wait(30)
    driver.find_element_by_id('j_username').clear()
    driver.find_element_by_id('j_username').send_keys(username)
    driver.find_element_by_id('j_password').clear()
    driver.find_element_by_id('j_password').send_keys(password)
    driver.find_element_by_class_name('bigFont').click()
    time.sleep(2)
    try:
        driver.find_element_by_xpath('//span[contains(text(),"XXXXXX")]').click()
        driver.find_element_by_class_name('bigFont').click()
    except:
        pass
    return driver

def editpw(driver):    #用例函式
    driver.implicitly_wait(20)
    time.sleep(3)
    driver.find_element_by_class_name('icon-dept').click()
    try:
        driver.find_element_by_xpath('//div[@id="guide_buttons"]/img[2]').click()
    except Exception as e:
        print e
    elems = driver.find_elements_by_class_name('clientsearch-grid-text')
    random.choice(elems).click()
    driver.find_element_by_class_name('reSetPassword').click()
    time.sleep(2)
    elem = driver.find_element_by_class_name('verification-code-img')    #定位驗證碼圖片
    value = identifyImage(driver,elem,'vCode.jpg')                        #呼叫Python圖片識別方法
    driver.find_element_by_class_name('verification-code-text').send_keys(value)    #輸入驗證碼
    time.sleep(2)
    driver.find_element_by_xpath('//span[contains(text(),"確認")]').click()
    try:
        message = driver.find_element_by_class_name('crm_prompt_text').text
        if message == u'密碼已重置,請接收簡訊和郵件通知!':
            return True
        return False
    except:
        return False
    
driver = login()
Boole = editpw(driver)
print Boole
driver.quit()

PS:登入驗證碼無需通過該方法處理,可以直接通過新增Cookie來繞過登入驗證碼,然後該方法只能識別一些簡單的圖片驗證碼!