Selenium&Pytesseract模拟登錄+驗證碼識别

發布時間:2018-08-21 20:14:09編輯:Run閱讀(5050)

    驗證碼是爬蟲需要解決的問題,因為很多網站的數據是需要登錄成功後才可以獲取的.

    驗證碼識别,即圖片識别,很多人都有誤區,覺得這是爬蟲方面的知識,其實是不對的.

    驗證碼識别涉及到的知識:人工智能,模式識别,機器視覺,圖像處理.

    主要流程:

    1 圖像采集:就直接通過HTTP抓HTML,然後分析出圖片的url,然後下載保存就可以了

    2 預處理:   檢測是正确的圖像格式,轉換到合适的格式,壓縮,剪切出ROI,去除噪音,灰度化,轉換色彩空間這些

    3 檢測:       驗證碼識别呢,主要是找出文字所在的主要區域

    4 前處理:   驗證碼識别,“一般”要做文字的切割

    5 訓練:       通過各種模式識别,機器學習算法,來挑選和訓練合适數量的訓練集

    6 識别:       輸入待識别的處理後的圖片,轉換成分類器需要的輸入格式,然後通過輸出的類和置信度,來判斷大概可能是 哪個字母


    Pytesseract--驗證碼識别

    1  簡介

    Python-tesseract是一款用于光學字符識别(OCR)的python工具,即從圖片中識别出其中嵌入的文字。Python-tesseract是對Google Tesseract-OCR的一層封裝。它也同時可以單獨作為對tesseract引擎的調用腳本,支持使用PIL庫(Python Imaging Library)讀取的各種圖片文件類型,包括jpeg、png、gif、bmp、tiff和其他格式,。作為腳本使用它将打印出識别出的文字而非寫入到文件。所以安裝pytesseract前要先安裝PIL和tesseract-orc這倆依賴庫


    2 安裝

    PIL安裝  Python平台的圖像處理标準庫

    pip3 install pillow


    pytesseract安裝,文字識别庫

    pip3 install pytesseract


    tesseract-ocr安裝,識别引擎

    windows:

    http://zapwpxmi.caifu68174.cn

    下載

    tesseract-ocr-setup-3.05.02 或者 tesseract-ocr-setup-4.0.0-alpha

    linux:

    github上面下載對應版本

    http://e83xttd0.caifu68174.cn


    遇到問題及解決:

    pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your path


    解決方法:(我是win環境)

    找到tesseract-ocr安裝目錄,複制路徑如:  C:\Program Files (x86)\Tesseract-OCR\tesseract.exe

    找到pytesseract.py文件,修改tesseract_cmd的路徑,如下:

    blob.png


    環境安裝完後,分析目标網站:

    華中科技大學  http://www.hust-snde.com/cms/

    需求,每天登陸一次保持活躍度

    可以看到這個登陸是需要輸入驗證碼的

    blob.png


    下面将利用Selenium&Pytesseract模拟登陸+驗證碼識别

    完整代碼如下:

    #!/usr/bin/env python
    # coding: utf-8
    
    import time
    from selenium import webdriver
    from PIL import Image
    import pytesseract
    
    
    class LoginSchool(object):
        def __init__(self, username, password, url):
            self.username = username
            self.password = password
            self.url = url
            self.browser = self.getbrowser()
            self.login_school(self.browser)
    
        def getbrowser(self):
            chrome_options = webdriver.ChromeOptions()
            # 去除警告
            chrome_options.add_argument('disable-infobars')
            # 無頭模式
            # chrome_options.set_headless()
            browser = webdriver.Chrome(options=chrome_options,
                                       executable_path=r'D:\chromedriver_2.41\chromedriver.exe')
            return browser
    
        def login_school(self, browser):
            browser.get(self.url)
            time.sleep(3)
            # 打開目标網站,并截取完整的圖片
            browser.get_screenshot_as_file('login.png')
            # 找到輸入賬号的input,并輸入賬号
            browser.find_element_by_id("loginId").send_keys(self.username)
            # 找到輸入密碼的input,并輸入密碼
            browser.find_element_by_id("passwd").send_keys(self.password)
            # 找到驗證碼img标簽,切圖
            img_code = browser.find_element_by_xpath("//div[@class='logif']//img[@id='imgCode']")
            time.sleep(3)
            # 算出驗證碼的四個點,即驗證碼四個角的坐标地址
            left = img_code.location['x']
            top = img_code.location['y']
            right = img_code.location['x'] + img_code.size['width']
            bottom = img_code.location['y'] + img_code.size['height']
            print("驗證碼坐标::", left, top, right, bottom)
            # 利用python的PIL圖片處理庫,利用坐标,切出驗證碼的圖
            im = Image.open('login.png')
            im = im.crop((left, top, right, bottom))
            im.save('code.png')
            # 調用圖片識别的函數,得到驗證碼
            code = self.img_to_str()
            # 找到驗證碼的input,并輸入驗證碼
            browser.find_element_by_id("authCode").send_keys(code)
            # 點擊登錄按鈕
            browser.find_element_by_xpath("//div[@class='loga']/a[text()=' 登 錄']").click()
            time.sleep(2)
            try:
                msg = browser.find_element_by_xpath("//div[@class='user_name']").text
                if msg:
                    print('登陸成功')
                    print(msg)
            except Exception as e:
                print('登陸失敗:{}'.format(e))
            finally:
                time.sleep(1)
                browser.quit()
    
        def img_to_str(self):
            # 打開切出的驗證碼code.png
            img = Image.open('code.png')
            # 利用pytesseract識别出驗證碼
            # -psm 8 為識别模式
            # -c tessedit_char_whitelist=1234567890  的意思是 識别純數字(0-9)
            code = pytesseract.image_to_string(img, config='-psm 8 -c tessedit_char_whitelist=1234567890')
            print('驗證碼識别:{}'.format(code))
            return code
    
    
    if __name__ == '__main__':
        username = '賬号'
        password = '密碼'
        url = 'http://www.hust-snde.com/center\
        /left_hydl.jsp?url=www.hust-snde.com:80/sso/login_centerLogin.action'
        st = LoginSchool(username=username, password=password, url=url)


    運行程序:

    blob.png


    當前目錄下會生成兩個圖片文件

    login.png 為登陸時的截圖

    blob.png


    code.png是從上面login.png中切出來的驗證碼圖片


    blob.png


    pytesseract識别簡單的驗證碼成功率還行,如果驗證碼有幹擾線,噪點之類的就需要對驗證碼圖片進行去除噪音,灰度化,轉換色彩空間這些處理.

    如果驗證碼有字體樣式,或者比較複雜,就需要訓練,來提高識别的成功率.

關鍵字