<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          巧用 selenium 解決驗(yàn)證碼,模擬登陸某流行網(wǎng)站

          共 7578字,需瀏覽 16分鐘

           ·

          2021-01-11 16:21

          一、前言

          1. 介紹

          驗(yàn)證碼多種多樣,有圖形文字的、有模擬點(diǎn)選的、有拖動滑動的,但其實(shí)歸根結(jié)底都需要人來對某種情形做一些判斷,然后把結(jié)果返回并提交。

          如果此時提交的驗(yàn)證碼結(jié)果是正確的,并且通過了一些驗(yàn)證碼的檢測,就能成功突破這個驗(yàn)證碼了。既然驗(yàn)證碼就是讓人來識別的,那么機(jī)器怎么辦呢?

          如果我們也不會什么算法,怎么去解這些驗(yàn)證碼呢?此時我們需要利用可以幫助我們來識別驗(yàn)證碼的工具或平臺就,讓工具或平臺把驗(yàn)證碼識別的結(jié)果返回給我們,我們拿著結(jié)果提交,那不就好了嗎?

          有專門的打碼平臺幫助我們來識別各種各樣的驗(yàn)證碼,平臺內(nèi)部對算法和人力做了集成,可以 7x24 小時來識別各種驗(yàn)證碼,包括識別圖形、坐標(biāo)點(diǎn)、缺口等各種驗(yàn)證碼,返回對應(yīng)的結(jié)果或坐標(biāo),正好可以解決我們的問題,比如超級鷹

          B站最新登錄驗(yàn)證為點(diǎn)選驗(yàn)證碼,以模擬登錄 B 站來熟悉 selenium 庫的使用和打碼平臺的使用方法。

          這個驗(yàn)證碼上面顯示了幾個漢字,同時在圖中也顯示了幾個漢字,我們需要按照順序依次點(diǎn)擊漢字在圖中的位置,點(diǎn)擊完成之后確認(rèn)提交,即可完成驗(yàn)證。這種驗(yàn)證碼如果我們沒有任何圖像識別算法基礎(chǔ)的話,是很難去識別的,所以這里我們可以借助打碼平臺來幫助我們識別漢字的位置。

          2. 準(zhǔn)備工作

          本文用到的 Python 庫是 Selenium,使用的瀏覽器為 Chrome,確保已經(jīng)正確安裝好 Selenium 庫、Chrome 瀏覽器,并配置好 ChromeDriver,

          使用的打碼平臺是超級鷹,鏈接為:https://www.chaojiying.com/,在使用之前請讀者自行注冊賬號并獲取一些題分供測試,另外還可以了解平臺可識別的驗(yàn)證碼的類別。

          打碼平臺能提供的服務(wù)種類一般都非常廣泛,可識別的驗(yàn)證碼類型也非常多,其中就包括點(diǎn)觸驗(yàn)證碼。

          超級鷹平臺同樣支持簡單的圖形驗(yàn)證碼識別,超級鷹平臺提供了如下一些服務(wù):

          • 英文數(shù)字:提供最多 20 位英文數(shù)字的混合識別;
          • 中文漢字:提供最多 7 個漢字的識別;
          • 純英文:提供最多 12 位的英文識別;
          • 純數(shù)字:提供最多 11 位的數(shù)字識別;
          • 任意特殊字符:提供不定長漢字英文數(shù)字、拼音首字母、計算題、成語混合、集裝箱號等字符的識別;
          • 坐標(biāo)選擇識別:如復(fù)雜計算題、選擇題四選一、問答題、點(diǎn)擊相同的字、物品、動物等返回多個坐標(biāo)的識別;

          本例需要處理的就是坐標(biāo)多選識別的情況。我們先將驗(yàn)證碼圖片提交給平臺,平臺會返回識別結(jié)果在圖片中的坐標(biāo)位置,然后我們再解析坐標(biāo)模擬點(diǎn)擊,下面我們就用程序來實(shí)現(xiàn)。

          二、實(shí)現(xiàn)思路

          三、Python代碼實(shí)現(xiàn)

          1. 獲取API

          通過官方網(wǎng)站下載對應(yīng)的 Python API,鏈接為:https://www.chaojiying.com/api-14.html。API 是 Python 2 版本的,用 requests 庫來實(shí)現(xiàn)的。我們可以簡單更改幾個地方,即可將其修改為 Python 3 版本。

          修改之后的 API 如下所示:

          #?-*-?coding:?UTF-8?-*-
          #?Chaojiying_Client類??用于提交要識別的圖片??返回json結(jié)果
          class?Chaojiying_Client(object):
          ????def?__init__(self,?username,?password,?soft_id):
          ????????self.username?=?username
          ????????password?=?password.encode('utf-8')
          ????????self.password?=?md5(password).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/5.0?(Windows?NT?6.1;?WOW64)?AppleWebKit/537.1?(KHTML,?like?Gecko)?Chrome/22.0.1207.1?Safari/537.1",
          ????????}

          ????def?PostPic(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)
          ????????logging.info(r.json())
          ????????return?r.json()

          ????def?ReportError(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)
          ????????logging.info(r.json())
          ????????return?r.json()

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

          • 最重要的一個方法叫作 post_pic,它需要傳入圖片對象和驗(yàn)證碼類型的代號。該方法會將圖片對象和相關(guān)信息發(fā)給超級鷹的后臺進(jìn)行識別,然后將識別成功的 json 返回。

          • 另一個方法叫作 report_error,它是發(fā)生錯誤時的回調(diào)。如果驗(yàn)證碼識別錯誤,調(diào)用此方法會返回相應(yīng)的題分。

          2. 分析B站登錄界面

          進(jìn)入登陸界面,定位用戶名和密碼對應(yīng)的標(biāo)簽,模擬輸入我們的賬號和密碼,點(diǎn)擊登錄,此時頁面會彈出驗(yàn)證碼。

          對進(jìn)行驗(yàn)證碼的獲取,然后提交給「超級鷹」進(jìn)行識別,接收到漢字的坐標(biāo)后,處理數(shù)據(jù),然后用動作鏈進(jìn)行模擬點(diǎn)擊操作,最后定位點(diǎn)擊確認(rèn),實(shí)現(xiàn)成功登錄 B 站。

          3. 具體實(shí)現(xiàn)

          導(dǎo)入用的庫

          from?selenium?import?webdriver
          from?time?import?sleep
          from?PIL?import?Image
          from?selenium.webdriver?import?ActionChains
          import?random
          import?requests
          from?hashlib?import?md5
          import?logging

          日志輸出和 webdriver.Chrome() 配置

          #?日志輸出配置
          logging.basicConfig(level=logging.INFO,?format='%(asctime)s?-?%(levelname)s:?%(message)s')
          #?初始化一個webdriver.Chrome()對象
          chrome_driver?=?r'D:\python\pycharm2020\chromedriver.exe'
          options?=?webdriver.ChromeOptions()
          #?關(guān)閉左上方?Chrome?正受到自動測試軟件的控制的提示
          options.add_experimental_option('useAutomationExtension',?False)
          options.add_experimental_option("excludeSwitches",?['enable-automation'])
          browser?=?webdriver.Chrome(options=options,?executable_path=chrome_driver)

          用 selenium 打開登錄頁面,進(jìn)行模擬登錄

          #?登錄函數(shù)???訪問頁面->輸出賬號、密碼->點(diǎn)擊登錄
          def?login():
          ????browser.get('https://passport.bilibili.com/login')
          ????browser.maximize_window()
          ????#?ID定位用戶名,密碼輸入框
          ????username?=?browser.find_element_by_id('login-username')
          ????password?=?browser.find_element_by_id('login-passwd')
          ????username.send_keys('your?username')
          ????password.send_keys('your?password')
          ????#?Xpath定位登錄按鈕并點(diǎn)擊
          ????browser.find_element_by_xpath('//*[@id="geetest-wrap"]/div/div[5]/a[1]').click()
          ????sleep(random.random()*3)

          將當(dāng)前頁面進(jìn)行截圖并保存下來,裁剪出驗(yàn)證碼區(qū)域

          def?save_img():
          ????# save_screenshot:將當(dāng)前頁面進(jìn)行截圖并保存下來
          ????browser.save_screenshot('page.png')
          ????#?Xpath定位驗(yàn)證碼圖片的位置
          ????code_img_ele?=?browser.find_element_by_xpath('/html/body/div[2]/div[2]/div[6]/div/div')
          ????location?=?code_img_ele.location??#?驗(yàn)證碼左上角的坐標(biāo)x,y
          ????size?=?code_img_ele.size??#?驗(yàn)證碼圖片對應(yīng)的長和寬

          ????#?得到左上角和右下角的坐標(biāo)
          ????rangle?=?(
          ????????int(location['x']?*?1.25),?int(location['y']?*?1.25),?int((location['x']?+?size['width'])?*?1.25),
          ????????int((location['y']?+?size['height'])?*?1.25)
          ????)
          ????image1?=?Image.open('./page.png')
          ????#?code_img_name?=?'./code.png'
          ????#?crop根據(jù)rangle元組內(nèi)的坐標(biāo)進(jìn)行裁剪?裁剪出驗(yàn)證碼區(qū)域
          ????frame?=?image1.crop(rangle)
          ????frame.save('./code.png')
          ????return?code_img_ele

          將點(diǎn)擊登錄后的頁面進(jìn)行截圖,然后定位到驗(yàn)證碼的位置,通過location()方法獲取驗(yàn)證碼左上角的坐標(biāo), size() 獲取驗(yàn)證碼的寬和高,左上角坐標(biāo)加上寬和高就是驗(yàn)證碼右下角的坐標(biāo)。獲取坐標(biāo)后就可以用 crop() 方法來進(jìn)行裁剪,然后將裁剪到的驗(yàn)證碼圖片保存。

          縮小圖片

          def?narrow_img():
          ????#?縮小圖片
          ????code?=?Image.open('./code.png')
          ????small_img?=?code.resize((169,?216))
          ????small_img.save('./small_img.png')
          ????print(code.size,?small_img.size)

          此時雖然獲取了驗(yàn)證碼圖片,但是還不能直接提交給超級鷹。因?yàn)槌夲椬R別的驗(yàn)證碼圖片的寬和高有限制,最好不超過460px*310px。但是截取到的驗(yàn)證碼圖片寬高為338px*432px,這時就要先將圖片縮小一倍再提交即可,等到收到坐標(biāo)數(shù)據(jù)再將坐標(biāo)乘2。

          將驗(yàn)證碼提交給超級鷹進(jìn)行識別

          def?submit_img():
          ????#?將驗(yàn)證碼提交給超級鷹進(jìn)行識別
          ????#?用戶中心->軟件ID?生成你的軟件ID->替換掉96001??綁定微信可以得到1000積分?免費(fèi)使用
          ????chaojiying?=?Chaojiying_Client('你的用戶名',?'密碼',?'生成的軟件ID')
          ????with?open('./small_img.png',?'rb')?as?f:
          ????????im?=?f.read()
          ????#?本地圖片文件路徑?來替換?a.jpg?有時WIN系統(tǒng)須要//
          ????result?=?chaojiying.PostPic(im,?9004)['pic_str']
          ????logging.info(result)
          ????return?result

          調(diào)用已獲取的API,傳入?yún)?shù):'你的用戶名', '密碼','生成的軟件ID'

          解析返回的漢字的坐標(biāo)點(diǎn)的結(jié)果

          def?parse_data(result):
          ????node_list?=?[]??#?存儲即將被點(diǎn)擊的點(diǎn)的坐標(biāo)??[[x1,y1],[x2,y2]]
          ????print(result)
          ????if?'|'?in?result:
          ????????nums?=?result.split('|')
          ????????for?i?in?range(len(nums)):
          ????????????x?=?int(nums[i].split(',')[0])
          ????????????y?=?int(nums[i].split(',')[1])
          ????????????xy_list?=?[x,?y]
          ????????????node_list.append(xy_list)
          ????else:
          ????????print(result.split(',')[0])
          ????????print(result.split(',')[1])
          ????????x?=?int(result.split(',')[0])
          ????????y?=?int(result.split(',')[1])
          ????????xy_list?=?[x,y]
          ????????node_list.append(xy_list)
          ????return?node_list

          超級鷹識別返回的結(jié)果的數(shù)據(jù)格式為:98,136|87,77 我們可以將數(shù)據(jù)以' | '進(jìn)行分割,保存到列表中,再以逗號分割將x,y的坐標(biāo)保存,得到[ [123,12],[234,21] ]這一格式,然后遍歷這一列表,使用動作鏈對每一個列表元素對應(yīng)的x,y指定的位置進(jìn)行模擬點(diǎn)擊操作,最后定位并點(diǎn)擊確認(rèn),可成功實(shí)現(xiàn)登錄 B 站。

          按順序模擬點(diǎn)擊每個坐標(biāo)點(diǎn)

          def?click_codeImg(all_list,?code_img_ele):
          ????#?遍歷列表,使用動作鏈對每一個列表元素對應(yīng)的x,y指定的位置進(jìn)行點(diǎn)擊操作
          ????for?item?in?all_list:
          ????????x?=?item[0]?*?1.6
          ????????y?=?item[1]?*?1.6
          ????????#?move_to_element_with_offset移動到距某個元素(左上角坐標(biāo))多少距離的位置
          ????????ActionChains(browser).move_to_element_with_offset(code_img_ele,?x,?y).click().perform()
          ????????sleep(random.random())
          ????????logging.info('點(diǎn)擊成功!')

          ????sleep(random.random()*2)
          ????#?完成動作鏈點(diǎn)擊操作后,定位確認(rèn)按鈕并點(diǎn)擊
          ????browser.find_element_by_xpath('/html/body/div[2]/div[2]/div[6]/div/div/div[3]/a').click()

          主函數(shù)調(diào)用

          #?-*-?coding:?UTF-8?-*-
          def?main():
          ????#?進(jìn)入登錄界面,輸入賬號密碼
          ????login()
          ????#?保存頁面截圖,并根據(jù)坐標(biāo)裁剪獲取驗(yàn)證碼圖片
          ????code_img_ele?=?save_img()
          ????#?縮小圖片
          ????narrow_img()
          ????#?將圖片提交給超級鷹,獲取返回的識別結(jié)果
          ????result?=?submit_img()
          ????#?解析返回結(jié)果,將數(shù)據(jù)格式化
          ????all_list?=?parse_data(result)
          ????#?在頁面驗(yàn)證碼上完成點(diǎn)擊操作并登錄
          ????click_codeImg(all_list,?code_img_ele)

          main()

          運(yùn)行效果如下:

          鼠標(biāo)是放在左邊的,沒有動過,不是人工悄悄點(diǎn)的哦,這樣我們就成功實(shí)現(xiàn)了 selenium 模擬登錄 B 站。

          作者:葉庭云?

          CSDN:https://yetingyun.blog.csdn.net/

          本文來自公眾號讀者投稿,歡迎各位童鞋向公號投稿,點(diǎn)擊下面圖片了解詳情!

          -END-

          瀏覽 43
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美成本人视频 | 69久久久| 欧美丰满少妇人妻精品 | 一级片在线播放 | 日本A片电影免费观看电影大全 |