Python + Selenium使用百度文字識(shí)別API識(shí)別驗(yàn)證碼

開發(fā)工具

PyCharm

需要安裝的包

python、Selenium、requests

先來一個(gè)簡(jiǎn)單的打開百度搜索的例子
from selenium import webdriver


class OpenBaidu:
    def __init__(self, search, openurl):
        self.search = search
        self.openurl = openurl

    def open(self):
        # 初始化瀏覽器對(duì)象
        option = webdriver.ChromeOptions()
        option.add_experimental_option('useAutomationExtension', False)
        option.add_experimental_option('excludeSwitches', ['enable-automation'])
        # 不自動(dòng)關(guān)閉瀏覽器
        option.add_experimental_option("detach", True)
        driver = webdriver.Chrome(options=option)
        # 設(shè)置瀏覽器長(zhǎng)寬
        driver.set_window_size(1200, 900)
        # 打開頁面
        driver.get(self.openurl)
        driver.find_element_by_id('kw').send_keys(self.search)
        driver.find_element_by_id('su').click()
        self.driver = driver

    def __call__(self):
        self.open()


if __name__ == '__main__':
    words = '北京時(shí)間'
    openUrl = 'http://www.baidu.com'
    OpenBaidu(words, openUrl)()

上面的代碼主要用到的方法:
browser = webdriver.Chrome()
browser.get(url)
//初始化瀏覽器對(duì)象 并打開對(duì)應(yīng)url
 browser .find_element_by_id('kw').send_keys(self.search)
 browser .find_element_by_id('su').click()
//輸入搜索關(guān)鍵字并點(diǎn)擊查詢按鈕
對(duì)輸入框的操作可參考鏈接:

Selenium-測(cè)試對(duì)象操作之:輸入框、按鈕

Selenium文檔:

參考鏈接一
參考鏈接二

首次運(yùn)行的時(shí)候可能會(huì)報(bào)如下錯(cuò)誤:

selenium.common.exceptions.WebDriverException: Message: ‘chromedriver’
參考鏈接
主要是相應(yīng)瀏覽器的驅(qū)動(dòng)版本不匹配導(dǎo)致的
打開自己電腦的瀏覽器(演示google瀏覽器)在地址欄輸入chrome://version/便可以查看到谷歌當(dāng)前的版本號(hào)
接著我們來到谷歌瀏覽器驅(qū)動(dòng)的下載網(wǎng)址http://chromedriver.storage.googleapis.com/index.html
下載對(duì)應(yīng)版本的驅(qū)動(dòng),解壓后就是chromedriver.exe
復(fù)制粘貼到以下兩個(gè)目錄:
C:\Program Files (x86)\Google\Chrome\Application
C:\Users\DHAdmin\PycharmProjects\pythonProject\venv\Scripts--python安裝目錄

不知道python安裝目錄的可運(yùn)行如下命令查看:
 import sys
 sys.path
本次案例:給惠網(wǎng)登錄并簽到

由于登錄有個(gè)圖片的驗(yàn)證碼,需要把圖片保存到本地以后用OCR進(jìn)行識(shí)別處理。
這里案例用到了百度文字識(shí)別OCR的API
用到的API網(wǎng)絡(luò)圖片文字識(shí)別
百度文字識(shí)別OCR文檔
目前大多數(shù)API都有可以免費(fèi)使用的次數(shù),注冊(cè)過程就省略了 。

操作步驟解析
  1. 初始化瀏覽器對(duì)象并打開需要登錄簽到的頁面
  2. 輸入用戶名和密碼
  3. 獲取驗(yàn)證碼圖片對(duì)圖片進(jìn)行識(shí)別,獲取文字
  4. 輸入識(shí)別出的文字點(diǎn)擊登錄按鈕
  5. 登錄成功后點(diǎn)擊簽到
第一步的步驟基本跟打開百度搜索類似
  # 初始化瀏覽器對(duì)象
  option = webdriver.ChromeOptions()
  option.add_experimental_option('useAutomationExtension', False)
  option.add_experimental_option('excludeSwitches', ['enable-automation'])
  # 不自動(dòng)關(guān)閉瀏覽器
  option.add_experimental_option("detach", True)
  driver = webdriver.Chrome(options=option)
  # 登陸頁面
  login_url = "https://www.geihui.com/b/daily_attendance.php"
  # 設(shè)置瀏覽器長(zhǎng)寬--窗口最大化
  driver.maximize_window()
  # 打開登陸頁面
  driver.get(login_url)
打開以后點(diǎn)擊登錄按鈕,如果未登錄會(huì)跳出登錄的彈窗,然后進(jìn)行登錄的操作
# 點(diǎn)擊簽到按鈕
driver.find_element_by_class_name('module-btn').click()
# 輸入用戶名密碼
driver.find_element_by_name('username').send_keys(self.username)
driver.find_element_by_name('password').send_keys(self.password)
獲取驗(yàn)證碼圖片保存到本地

截取完整頁面和指定元素并保存為圖片--參考鏈接

# 截取整個(gè)頁面
driver.get_screenshot_as_file("test.png")
driver.save_screenshot("test.png")
# 找到搜索框
imgposition = driver.find_element_by_id("n_code_img")
# 截取搜索框元素
imgposition.screenshot("img.png")
接下來就是對(duì)圖片進(jìn)行識(shí)別了,由于識(shí)別圖片需要帶token 所以要先獲取百度文字識(shí)別OCR的token
# 放一個(gè)官網(wǎng)提供的請(qǐng)求token的示例
# encoding:utf-8
import requests 

# client_id 為官網(wǎng)獲取的AK, client_secret 為官網(wǎng)獲取的SK
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【官網(wǎng)獲取的AK】&client_secret=【官網(wǎng)獲取的SK】'
response = requests.get(host)
if response:
    print(response.json())
文字識(shí)別的API有好多,要用哪種可以自己參考文檔選擇-這里用到的是網(wǎng)絡(luò)圖片文字識(shí)別,每天有500次免費(fèi)調(diào)用的次數(shù),后期是否會(huì)收費(fèi)未知。還是放一個(gè)官網(wǎng)調(diào)用的示例(如果是點(diǎn)選驗(yàn)證碼的話需要返回位置
# encoding:utf-8

import requests
import base64

'''
網(wǎng)絡(luò)圖片文字識(shí)別
'''

request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/webimage"
# 二進(jìn)制方式打開圖片文件
f = open('[本地文件]', 'rb')
img = base64.b64encode(f.read())

params = {"image":img}
access_token = '[調(diào)用鑒權(quán)接口獲取的token]'
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
    print (response.json())
有了識(shí)別結(jié)果以后,只要獲取到文字進(jìn)行輸入,再點(diǎn)擊登錄,到此已經(jīng)完成了70%了。由于文字識(shí)別并不是百分百有返回結(jié)果的,所以我們需要加上一個(gè)判斷,如果沒有識(shí)別出來的時(shí)候,點(diǎn)擊刷新驗(yàn)證碼按鈕,,重新對(duì)圖片進(jìn)行保存然后識(shí)別。
            if response:
                if len(response.json().get('words_result')) > 0:
                    # 輸入驗(yàn)證碼文字
                    self.driver.find_element_by_id('top_loginvc').send_keys(response.json().get('words_result')[0].get('words'))
                    # 點(diǎn)擊登錄
                    self.driver.find_element_by_xpath('//*[@id="uloginfo"]/div[4]/input').click()
                    time.sleep(3)
                    # 點(diǎn)擊簽到
                    try:
                        self.driver.find_element_by_class_name('module-btn').click()
                        # print(response.json())
                        # return response.json().get('words_result')
                    except:
                        self.refreshcode()

                else:
                    self.refreshcode()

    def refreshcode(self):
        # 點(diǎn)擊刷新驗(yàn)證碼
        self.driver.find_element_by_css_selector('.refresh.pngBase').click()
        time.sleep(3)
        # 保存新的驗(yàn)證碼圖片覆蓋原來的
        # 截取整個(gè)頁面
        self.driver.get_screenshot_as_file("test.png")
        self.driver.save_screenshot("test.png")
        # 找到搜索框
        imgposition = self.driver.find_element_by_id("n_code_img")
        # 截取搜索框元素

        imgposition.screenshot("img.png")
        # 重新登陸
        self.ocr_b64()

完整代碼
import time

import requests
from selenium import webdriver
import base64

APP_ID = 'APP_ID'  # 填寫你的API Key
SECRET_KEY = 'SECRET_KEY'  # 填寫你的Secret Key

TOKEN_URL = 'https://aip.baidubce.com/oauth/2.0/token'  # 獲取token請(qǐng)求url

OCR_URL = 'https://aip.baidubce.com/rest/2.0/ocr/v1/webimage' # 文字識(shí)別OCRAPI


class Check:
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def check(self):
        # 初始化瀏覽器對(duì)象
        option = webdriver.ChromeOptions()
        option.add_experimental_option('useAutomationExtension', False)
        option.add_experimental_option('excludeSwitches', ['enable-automation'])
        # 不自動(dòng)關(guān)閉瀏覽器
        option.add_experimental_option("detach", True)
        driver = webdriver.Chrome(options=option)
        # 登陸頁面
        login_url = "https://www.geihui.com/b/daily_attendance.php"
        # 設(shè)置瀏覽器長(zhǎng)寬
        driver.maximize_window()
        # driver.set_window_size(1200, 900)
        # 打開登陸頁面
        driver.get(login_url)
        # 點(diǎn)擊簽到按鈕
        driver.find_element_by_class_name('module-btn').click()
        # 輸入用戶名密碼
        driver.find_element_by_name('username').send_keys(self.username)
        driver.find_element_by_name('password').send_keys(self.password)
        # 截取整個(gè)頁面
        driver.get_screenshot_as_file("test.png")
        driver.save_screenshot("test.png")
        # 找到搜索框
        imgposition = driver.find_element_by_id("n_code_img")
        # 截取搜索框元素
        imgposition.screenshot("img.png")
        self.driver = driver

    def fetch_token(self):
        data = {
            'grant_type': 'client_credentials',
            'client_id': APP_ID,
            'client_secret': SECRET_KEY
        }
        r = requests.post(TOKEN_URL, data=data)
        if 'access_token' in r.json():
            # print(r.json())
            return r.json().get('access_token')
        else:
            print('請(qǐng)檢查獲取access_token的URL, APP_ID, SECRET_KEY!')

    def ocr_b64(self):
        '''
        傳入base64編碼格式的圖片數(shù)據(jù),識(shí)別圖片中的文字
        :params: base64編碼格式的圖片數(shù)據(jù)
        :return: 返回識(shí)別后的文字字符串
        '''
        access_token = self.fetch_token()  # 獲取 token
        # 打開本地圖片
        f = open('./img.png', 'rb')
        img = base64.b64encode(f.read())
        if access_token:
            params = {"image": img}
            access_token = access_token
            request_url = OCR_URL + "?access_token=" + access_token
            headers = {'content-type': 'application/x-www-form-urlencoded'}
            response = requests.post(request_url, data=params, headers=headers)
            if response:
                if len(response.json().get('words_result')) > 0:
                    # 輸入驗(yàn)證碼文字
                    self.driver.find_element_by_id('top_loginvc').send_keys(response.json().get('words_result')[0].get('words'))
                    # 點(diǎn)擊登錄
                    self.driver.find_element_by_xpath('//*[@id="uloginfo"]/div[4]/input').click()
                    time.sleep(3)
                    # 點(diǎn)擊簽到
                    try:
                        self.driver.find_element_by_class_name('module-btn').click()
                        # print(response.json())
                        # return response.json().get('words_result')
                    except:
                        self.refreshcode()

                else:
                    self.refreshcode()

    def refreshcode(self):
        # 點(diǎn)擊刷新驗(yàn)證碼
        self.driver.find_element_by_css_selector('.refresh.pngBase').click()
        time.sleep(3)
        # 保存新的驗(yàn)證碼圖片覆蓋原來的
        # 截取整個(gè)頁面
        self.driver.get_screenshot_as_file("test.png")
        self.driver.save_screenshot("test.png")
        # 找到搜索框
        imgposition = self.driver.find_element_by_id("n_code_img")
        # 截取搜索框元素

        imgposition.screenshot("img.png")
        # 重新登陸
        self.ocr_b64()

    def __call__(self):
        self.check()
        time.sleep(3)
        self.fetch_token()
        time.sleep(3)
        self.ocr_b64()


if __name__ == '__main__':
    # 用戶名和密碼
    username = 'xxxxx'
    password = 'xxxxx'
    Check(username, password)()

第一次寫代碼還可進(jìn)行完善,有興趣的可以拿去改改試試

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容