驗證碼是爬蟲需要解決的問題,因為很多網站的數據是需要登錄成功后才可以獲取的.
驗證碼識別,即圖片識別,很多人都有誤區,覺得這是爬蟲方面的知識,其實是不對的.
驗證碼識別涉及到的知識:人工智能,模式識別,機器視覺,圖像處理.
主要流程:
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:
https://digi.bib.uni-mannheim.de/tesseract/
下載
tesseract-ocr-setup-3.05.02 或者 tesseract-ocr-setup-4.0.0-alpha
linux:
github上面下載對應版本
https://github.com/tesseract-ocr/tesseract
遇到問題及解決:
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的路徑,如下:

環境安裝完后,分析目標網站:
華中科技大學 http://www.hust-snde.com/cms/
需求,每天登陸一次保持活躍度
可以看到這個登陸是需要輸入驗證碼的

下面將利用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)
運行程序:

當前目錄下會生成兩個圖片文件
login.png 為登陸時的截圖

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

pytesseract識別簡單的驗證碼成功率還行,如果驗證碼有干擾線,噪點之類的就需要對驗證碼圖片進行去除噪音,灰度化,轉換色彩空間這些處理.
如果驗證碼有字體樣式,或者比較復雜,就需要訓練,來提高識別的成功率.
