天天看點

使用OCR技術識别圖形驗證碼

爬蟲過程中難免會遇到各種各樣的驗證碼,而大多數驗證碼還是圖形驗證碼,這時候我們可以直接用 OCR 來識别。

一、OCR技術

OCR,即 ​

​Optical Character Recognition​

​,中文叫作光學字元識别,是指通過電子裝置檢查列印在紙上的字元,通過檢查暗、亮的模式确認字元形狀,然後通過字元識别方法将形狀轉換成計算機文字的過程。

那麼對于圖形驗證碼來說,它都是一些不規則的字元,但是這些字元确實是由字元稍加扭曲變換得到的内容。

爬蟲過程中難免會遇到各種各樣的驗證碼,而大多數驗證碼還是圖形驗證碼,這時候我們可以直接用 OCR 來識别。

二、整體代碼邏輯

1.打開有驗證碼填寫的網站(​​https://captcha7.scrape.center/​​);

2.找到使用者名輸入框,輸入使用者名;

3.找到密碼輸入框,輸入密碼;

4.找到并截取驗證碼圖檔,轉化為圖檔對象;

5.預處理驗證碼圖檔,去除噪聲;

6.識别驗證碼,得到識别結果;

7.去除識别結果中的一些非字母字元和數字字元;

8.找到驗證碼輸入框,輸入驗證碼結果;

9.點選“登入”按鈕;

10.等待“登入成功”的字樣出現,如果出現就證明驗證碼識别正确,否則重複以上步驟。

示例代碼:

# -*- UTF-8 -*-
"""
@File:test.py
@Description:
@Author:echohye
@Date:2022/02/03 18:11
"""

import time
import re
import tesserocr
from selenium import webdriver
from io import BytesIO
from PIL import Image
from retrying import retry
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
import numpy as np

def preprocess(image):
    image = image.convert('L')
    array = np.array(image)
    array = np.where(array > 150, 255, 0)
    image = Image.fromarray(array.astype('uint8'))
    return image

@retry(stop_max_attempt_number=10, retry_on_result=lambda x: x is False)
def login():
    browser.get('https://captcha7.scrape.center/')
    browser.find_element(By.CSS_SELECTOR, '.username input[type="text"]').send_keys('admin')
    browser.find_element(By.CSS_SELECTOR, '.password input[type="password"]').send_keys('admin')
    captcha = browser.find_element(By.CSS_SELECTOR, '#captcha')
    image = Image.open(BytesIO(captcha.screenshot_as_png))
    image = preprocess(image)
    captcha = tesserocr.image_to_text(image)
    captcha = re.sub('[^A-Za-z0-9]', '', captcha)
    browser.find_element(By.CSS_SELECTOR, '.captcha input[type="text"]').send_keys(captcha)
    browser.find_element(By.CSS_SELECTOR, '.login').click()
    try:
        WebDriverWait(browser, 3).until(EC.presence_of_element_located((By.XPATH, '//h2[contains(., "登入成功")]')))
        time.sleep(10)
        browser.close()
        return True
    except TimeoutException:
        return False

if __name__ == '__main__':
    browser = webdriver.Chrome()
    login()      

​​selenium運作失敗?點選我檢視解決方法​​

​tesserocr安裝失敗?點選我檢視解決方法

運作展示

使用OCR技術識别圖形驗證碼
使用OCR技術識别圖形驗證碼