欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python3爬蟲關(guān)于識別點觸點選驗證碼的實例講解

 更新時間:2020年07月30日 14:49:47   作者:愛喝馬黛茶的安東尼  
在本篇文章里小編給大家整理了關(guān)于Python3爬蟲關(guān)于識別點觸點選驗證碼的實例講解內(nèi)容,需要的朋友們可以參考下。

上一節(jié)我們實現(xiàn)了極驗驗證碼的識別,但是除了極驗其實還有另一種常見的且應用廣泛的驗證碼,比較有代表性的就是點觸驗證碼。

可能你對這個名字比較陌生,但是肯定見過類似的驗證碼,比如 12306,這就是一種典型的點觸驗證碼,如圖所示:

018a2c46924f7b1536f5a647e66e19d.png

我們需要直接點擊圖中符合要求的圖,如果所有答案均正確才會驗證成功,如果有一個答案錯誤,驗證就會失敗,這種驗證碼就可以稱之為點觸驗證碼。

另外還有一個專門提供點觸驗證碼服務(wù)的站點,叫做 TouClick,其官方網(wǎng)站為:https://www.touclick.com/,本節(jié)就以它為例講解一下此類驗證碼的識別過程。

1. 本節(jié)目標

本節(jié)我們的目標是用程序來識別并通過點觸驗證碼的驗證。

2. 準備工作

本次我們使用的 Python 庫是 Selenium,使用的瀏覽器為 Chrome,在此之前請確保已經(jīng)正確安裝好了 Selenium 庫、Chrome瀏覽器并配置好了 ChromeDriver,相關(guān)流程可以參考第一章的說明。

3. 了解點觸驗證碼

TouClick 官方網(wǎng)站的驗證碼樣式如圖 8-19 所示:

c2d4ad8c4f0400e0aaf2562dbb2dbba.png

和 12306 站點有相似之處,不過這次是點擊圖片中的文字,不是圖片了,另外還有各種形形色色的點觸驗證碼,其交互形式可能略有不同,但基本原理都是類似的。

接下來我們就來統(tǒng)一實現(xiàn)一下此類點觸驗證碼的識別過程。

4. 識別思路

此種驗證碼的如果依靠圖像識別的話識別難度非常之大。

例如就 12306 來說,其識別難點有兩個點,第一點是文字識別,如圖 8-20 所示:

a8ca608bae88401a810bdf35b9cf1fd.png

如點擊圖中所有的漏斗,“漏斗”二字其實都經(jīng)過變形、放縮、模糊處理了,如果要借助于前面我們講的 OCR 技術(shù)來識別,識別的精準度會大打折扣,甚至得不到任何結(jié)果。第二點是圖像的識別,我們需要將圖像重新轉(zhuǎn)化文字,可以借助于各種識圖接口,可經(jīng)我測試識別正確結(jié)果的準確率非常低,經(jīng)常會出現(xiàn)匹配不正確或匹配不出結(jié)果的情況,而且圖片本身的的清晰度也不夠,所以識別難度會更大,更何況需要同時識別出八張圖片的結(jié)果,且其中幾個答案需要完全匹配正確才能驗證通過,綜合來看,此種方法基本是不可行的。

再拿 TouClick 來說,如圖所示:

198a07f9eaa25def2fd353d9af22b99.png

我們需要從這幅圖片中識別出植株二字,但是圖片的背景或多或少會有干擾,導致 OCR 幾乎不會識別出結(jié)果,有人會說,直接識別白色的文字不就好了嗎?但是如果換一張驗證碼呢?如圖 8-22 所示:

ca1e7d50d2a63914e072c728013dd01.png

這張驗證碼圖片的文字又變成了藍色,而且還又有白色陰影,識別的難度又會大大增加。

那么此類驗證碼就沒法解了嗎?答案當然是有,靠什么?靠人。

靠人解決?那還要程序做什么?不要急,這里說的人并不是我們自己去解,在互聯(lián)網(wǎng)上存在非常多的驗證碼服務(wù)平臺,平臺 7×24 小時提供驗證碼識別服務(wù),一張圖片幾秒就會獲得識別結(jié)果,準確率可達 90% 以上,但是就需要花點錢來購買服務(wù)了,畢竟平臺都是需要盈利的,不過不用擔心,識別一個驗證碼只需要幾分錢。

在這里我個人比較推薦的一個平臺是超級鷹。

其提供的服務(wù)種類非常廣泛,可識別的驗證碼類型非常多,其中就包括此類點觸驗證碼。

另外超級鷹平臺同樣支持簡單的圖形驗證碼識別,如果 OCR 識別有難度,同樣可以用本節(jié)相同的方法借助此平臺來識別,下面是此平臺提供的一些服務(wù):

英文數(shù)字,提供最多20位英文數(shù)字的混合識別

中文漢字,提供最多7個漢字的識別

純英文,提供最多12位的英文的識別

純數(shù)字,提供最多11位的數(shù)字的識別

任意特殊字符,提供不定長漢字英文數(shù)字、拼音首字母、計算題、成語混合、 集裝箱號等字符的識別

坐標選擇識別,如復雜計算題、選擇題四選一、問答題、點擊相同的字、物品、動物等返回多個坐標的識別

而本節(jié)我們需要解決的就是屬于最后一類,坐標多選識別的情況,我們需要做的就是將驗證碼圖片提交給平臺,然后平臺會返回識別結(jié)果在圖片中的坐標位置,接下來我們再解析坐標模擬點擊就好了。

原理非常簡單,下面我們就來實際用程序來實驗一下。

5. 注冊賬號

在開始之前,我們需要先注冊一個超級鷹賬號并申請一個軟件ID,注冊頁面鏈接為:https://www.chaojiying.com/user/reg/,注冊完成之后還需要在后臺開發(fā)商中心添加一個軟件ID,最后一件事就是充值一些題分,充值多少可以根據(jù)價格和識別量自行決定。

6. 獲取API

做好上面的準備工作之后我們就可以開始用程序來對接驗證碼的識別了。

首先我們可以到官方網(wǎng)站下載對應的 Python API,鏈接為:https://www.chaojiying.com/api-14.html,但是此 API 是Python2 版本的,是用 Requests 庫來實現(xiàn)的,我們可以簡單更改幾個地方即可將其修改為 Python3 版本。

修改之后的API如下:

import requests
from hashlib import md5
class Chaojiying(object):
    def __init__(self, username, password, soft_id):
        self.username = username
        self.password = md5(password.encode('utf-8')).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }
    def post_pic(self, im, codetype):
        """
        im: 圖片字節(jié)
        codetype: 題目類型 參考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, 
        headers=self.headers)
        return r.json()
    def report_error(self, im_id):
        """
        im_id:報錯題目的圖片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()

這里定義了一個 Chaojiying 類,其構(gòu)造函數(shù)接收三個參數(shù),分別是超級鷹的用戶名、密碼以及軟件ID,保存好以備使用。

接下來是最重要的一個方法叫做 post_pic(),這里需要傳入圖片對象和驗證碼的代號,該方法會將圖片對象和相關(guān)信息發(fā)給超級鷹的后臺進行識別,然后將識別成功的 Json 返回回來。

另一個方法叫做 report_error(),這個是發(fā)生錯誤的時候的回調(diào),如果驗證碼識別錯誤,調(diào)用此方法會返還相應的題分。

接下來我們以 TouClick 的官網(wǎng)為例來進行演示點觸驗證碼的識別過程,鏈接為:http://admin.touclick.com/,如果沒有注冊賬號可以先注冊一個。

7. 初始化

首先我們需要初始化一些變量,如 WebDriver、Chaojiying對象等等,代碼實現(xiàn)如下:

EMAIL = 'cqc@cuiqingcai.com'
PASSWORD = ''
# 超級鷹用戶名、密碼、軟件ID、驗證碼類型
CHAOJIYING_USERNAME = 'Germey'
CHAOJIYING_PASSWORD = ''
CHAOJIYING_SOFT_ID = 893590
CHAOJIYING_KIND = 9102
class CrackTouClick():
    def __init__(self):
        self.url = 'http://admin.touclick.com/login.html'
        self.browser = webdriver.Chrome()
        self.wait = WebDriverWait(self.browser, 20)
        self.email = EMAIL
        self.password = PASSWORD
        self.chaojiying = Chaojiying(CHAOJIYING_USERNAME, CHAOJIYING_PASSWORD, CHAOJIYING_SOFT_ID)

這里的賬號和密碼請自行修改。

8. 獲取驗證碼

接下來的第一步就是完善相關(guān)表單,然后模擬點擊呼出驗證碼,此步非常簡單,代碼實現(xiàn)如下:

def open(self):
    """
    打開網(wǎng)頁輸入用戶名密碼
    :return: None
    """
    self.browser.get(self.url)
    email = self.wait.until(EC.presence_of_element_located((By.ID, 'email')))
    password = self.wait.until(EC.presence_of_element_located((By.ID, 'password')))
    email.send_keys(self.email)
    password.send_keys(self.password)
def get_touclick_button(self):
    """
    獲取初始驗證按鈕
    :return:
    """
    button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'touclick-hod-wrap')))
    return button

在這里 open() 方法負責填寫表單,get_touclick_button() 方法則是獲取驗證碼按鈕,隨后觸發(fā)點擊即可。

接下來我們需要類似上一節(jié)極驗驗證碼圖像獲取一樣,首先獲取驗證碼圖片的位置和大小,隨后從網(wǎng)頁截圖里面截取相應的驗證碼圖片就好了。代碼實現(xiàn)如下:

def get_touclick_element(self):
    """
    獲取驗證圖片對象
    :return: 圖片對象
    """
    element = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'touclick-pub-content')))
    return element
def get_position(self):
    """
    獲取驗證碼位置
    :return: 驗證碼位置元組
    """
    element = self.get_touclick_element()
    time.sleep(2)
    location = element.location
    size = element.size
    top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[
        'width']
    return (top, bottom, left, right)
def get_screenshot(self):
    """
    獲取網(wǎng)頁截圖
    :return: 截圖對象
    """
    screenshot = self.browser.get_screenshot_as_png()
    screenshot = Image.open(BytesIO(screenshot))
    return screenshot
def get_touclick_image(self, name='captcha.png'):
    """
    獲取驗證碼圖片
    :return: 圖片對象
    """
    top, bottom, left, right = self.get_position()
    print('驗證碼位置', top, bottom, left, right)
    screenshot = self.get_screenshot()
    captcha = screenshot.crop((left, top, right, bottom))
    return captcha

在這里 get_touclick_image() 方法即為從網(wǎng)頁截圖中截取對應的驗證碼圖片,其中驗證碼圖片的相對位置坐標由 get_position() 方法返回得到,最后我們得到的是一個 Image 對象。

9. 識別驗證碼

隨后我們調(diào)用 Chaojiying 對象的 post_pic() 方法即可把圖片發(fā)送給超級鷹后臺,在這里發(fā)送的圖像是字節(jié)流格式,代碼實現(xiàn)如下:

image = self.get_touclick_image()
bytes_array = BytesIO()
image.save(bytes_array, format='PNG')
# 識別驗證碼
result = self.chaojiying.post_pic(bytes_array.getvalue(), CHAOJIYING_KIND)
print(result)

這樣運行之后 result 變量就是超級鷹后臺的識別結(jié)果,可能運行需要等待幾秒,畢竟后臺還有人工來完成識別。

返回的結(jié)果是一個 Json,如果識別成功后一個典型的返回結(jié)果類似如下:

{'err_no': 0, 'err_str': 'OK', 'pic_id': '6002001380949200001', 'pic_str': '132,127|56,77', 'md5': '1f8e1d4bef8b
11484cb1f1f34299865b'}

其中 pic_str 就是識別的文字的坐標,是以字符串形式返回的,每個坐標都以 | 分隔,所以接下來我們只需要將其解析之后再模擬點擊即可,代碼實現(xiàn)如下:

def get_points(self, captcha_result):
    """
    解析識別結(jié)果
    :param captcha_result: 識別結(jié)果
    :return: 轉(zhuǎn)化后的結(jié)果
    """
    groups = captcha_result.get('pic_str').split('|')
    locations = [[int(number) for number in group.split(',')] for group in groups]
    return locations
 
def touch_click_words(self, locations):
    """
    點擊驗證圖片
    :param locations: 點擊位置
    :return: None
    """
    for location in locations:
        print(location)
        ActionChains(self.browser).move_to_element_with_offset(self.get_touclick_element(), location[0], 
        location[1]).click().perform()
        time.sleep(1)

在這里我們用 get_points() 方法將識別結(jié)果變成了列表的形式,最后 touch_click_words() 方法則通過調(diào)用 move_to_element_with_offset() 方法依次傳入解析后的坐標,然后點擊即可。

這樣我們就可以模擬完成坐標的點選了,運行效果如圖所示:

4f2df8854a82238ebc24cf8a80d658f.png

最后我們需要做的就是點擊提交驗證的按鈕等待驗證通過,再點擊登錄按鈕即可成功登錄,后續(xù)實現(xiàn)在此不再贅述。

這樣我們就借助于在線驗證碼平臺完成了點觸驗證碼的識別,此種方法也是一種通用方法,用此方法來識別 12306 等驗證碼也是完全相同的原理。

10. 本節(jié)代碼

本節(jié)代碼地址為:https://github.com/Python3WebSpider/CrackTouClick

11. 結(jié)語

本節(jié)我們通過在線打碼平臺輔助完成了驗證碼的識別,這種識別方法非常強大,幾乎任意的驗證碼都可以識別,如果遇到難題,借助于打碼平臺無疑是一個極佳的選擇。

相關(guān)文章

  • 通過案例解析python鴨子類型相關(guān)原理

    通過案例解析python鴨子類型相關(guān)原理

    這篇文章主要介紹了通過案例解析python鴨子類型相關(guān)原理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • Python常見讀寫文件操作實例總結(jié)【文本、json、csv、pdf等】

    Python常見讀寫文件操作實例總結(jié)【文本、json、csv、pdf等】

    這篇文章主要介紹了Python常見讀寫文件操作,結(jié)合實例形式總結(jié)分析了Python常見的各種文件讀寫操作,包括文本、json、csv、pdf等文件的讀寫與相關(guān)注意事項,需要的朋友可以參考下
    2019-04-04
  • Python+folium繪制精美地圖的示例詳解

    Python+folium繪制精美地圖的示例詳解

    folium是一個基于leaflet.js的python地圖庫,可以通過folium來操縱數(shù)據(jù),并將其可視化。本文將通過各種示例詳細講解如何利用folium繪制精美地圖,需要的可以參考一下
    2022-03-03
  • python 批量壓縮圖片的腳本

    python 批量壓縮圖片的腳本

    用Python編寫的批量壓縮圖片的腳本,可以自定義壓縮質(zhì)量,有批量圖片壓縮需求的朋友可以直接拿來用
    2021-06-06
  • PyQt5中QTableWidget如何彈出菜單的示例代碼

    PyQt5中QTableWidget如何彈出菜單的示例代碼

    這篇文章主要介紹了PyQt5中QTableWidget如何彈出菜單的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • Python操作MySQL數(shù)據(jù)庫9個實用實例

    Python操作MySQL數(shù)據(jù)庫9個實用實例

    這篇文章主要介紹了Python操作MySQL數(shù)據(jù)庫9個實用實例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2015-12-12
  • tensorflow-gpu安裝的常見問題及解決方案

    tensorflow-gpu安裝的常見問題及解決方案

    這篇文章主要介紹了tensorflow-gpu安裝的常見問題及解決方案,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友參考下吧,需要的朋友可以參考下
    2020-01-01
  • 解決Pyinstaller打包軟件失敗的一個坑

    解決Pyinstaller打包軟件失敗的一個坑

    這篇文章主要介紹了解決Pyinstaller打包軟件失敗的一個坑,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Python?ini配置文件示例詳解

    Python?ini配置文件示例詳解

    這篇文章主要給大家介紹了關(guān)于Python?ini配置文件的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2022-03-03
  • Python技巧匿名函數(shù)、回調(diào)函數(shù)和高階函數(shù)

    Python技巧匿名函數(shù)、回調(diào)函數(shù)和高階函數(shù)

    本文分享的是Python技巧匿名函數(shù)、回調(diào)函數(shù)和高階函數(shù),我們在Python中使用lambda表達式來使用匿名函數(shù),回調(diào)函數(shù)即callback,先寫一個函數(shù),讓預先寫好的系統(tǒng)來調(diào)用,一個函數(shù)可以作為參數(shù)傳給另外一個函數(shù),或者一個函數(shù)的返回值為另外一個函數(shù),滿足其一則為高階函數(shù)
    2021-12-12

最新評論