iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
Software Development

QA 三十天養成日記系列 第 20

[Day20][小技巧] 破解圖形驗證碼!使用 Python + 2Captcha 兩步驟就行了!

  • 分享至 

  • xImage
  •  

captcha 存在的目的也是為了阻擋機器人/非正當的操作,但我們的自動化測試就都是機器人了...所以最終這樣自動化就會有卡住不穩定的可能性。

captcha 目前市場大約分兩大類

  • 基本驗證碼
    基本驗證碼

  • google recaptcha 系列
    google recaptcha V2/V3 版本(頁面自動判斷是否機器人)
    不論 V2 V3 版本,如果是判定機器人操作,它就會要求你找公車、消防車、大卡車...XD

所以!既然我們要做自動化!那就不應該被這種小事給絆住!今天就再突破極限吧~


2Captcha

我們使用的圖像辨識平台為 2Captcha,這個平台是需要收費。
我自己是先刷了 5 USD,基本它的用量費用很便宜,最重要的就是計費方式

基本驗證碼:目前是每 1,000 次驗證 USD0.5


另外也支援你進行人工辨識圖形,進而就能賺取一些費用

所以整體上是非常夠用的
這個 2Captcha API 同時也有支援上方說的的 Google reCaptcha v2/v3 及一般基本圖形驗證碼
也支援多種不同的程式語言近行編寫
e.g. Python、PHP、JavaScript、GO、C#、Ruby等。


使用教學 (Python)

以下教學先以 基本的驗證碼 為主,下次會在介紹 google recaptcha 系列

Step1.註冊取API Key

請先前往 2Captcha 的連結進行註冊:https://2captcha.com/auth/register
申請完後會取得 API Key,請把這組Key記下來

然後請綁加值一點點錢進去。
我個人是加值了 5 美金,測到現在還有 4.92 美,所以真的是很俗!

Step2. Coding 範例

將會用到以下兩個 2Captcha API

import time
import base64
import requests
import json

#先將圖形驗證碼取下來變成圖片檔,並且取的該圖檔
file = {'file': open('captcha.png', 'rb')} 

# 你的 2captcha KEY
api_key = 'Input Your 2captcha KEY' 
payload = {
  'key': api_key,
}

# 代表一般驗證碼(Normal Captcha)提交成功
response = requests.post('http://2captcha.com/in.php', files = file, params = payload) 

# e.g. response:OK|67645583547,後面的數字則是驗證碼ID
print(f'response:{response.text}')

# 判斷回傳 api 結果是否正確
if response.ok and response.text.find('OK') > -1:
    # 擷取驗證碼ID
    captcha_id = response.text.split('|')[1]  
    # 由於 2Captcha 服務有時無法即時辨識與回應結果,所以實作一個 retry 機制
    for i in range(10):
        # 取得辨識結果,帶入你的 api_key 跟剛剛擷取的 captcha_id
        response = requests.get(f'http://2captcha.com/res.php?key={api_key}&action=get&id={captcha_id}')
        # 若尚未辨識完成,休息個三秒,會在 for 開頭再跑一次
        if response.text.find('CAPCHA_NOT_READY') > -1: 
          time.sleep(3)
        # 若辨識完成正確
        elif response.text.find('OK') > -1:
          # 擷取正確辨識結果 
          captcha_text = response.text.split('|')[1]  
    else:
      print('取得驗證碼發生錯誤!')

特殊情況

有些網站在取得圖形驗證碼時有做一些特別判斷
如果直接下載驗證碼圖片,通常該驗證碼會在自動重新取得,也就是你當下取的驗證碼就會變成是舊的。
如果要避免這種情況發生
可以使用 Js canvas 方式模擬繪製出驗證碼並儲存在本地端。

# 可搭配 selenium 方式模擬操作網站
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager

options = Options()
options.add_argument("--disable-notifications")
chrome = webdriver.Chrome('你的 chromedriver 路徑', chrome_options=options)
chrome.get('你的網址')

# 使用 Js canvas 繪製一個當前的 captcha
img_base64 =chrome.execute_script("""
  var ele = arguments[0];
  var cnv = document.createElement('canvas');
  cnv.width = ele.width; cnv.height = ele.height;
  cnv.getContext('2d').drawImage(ele, 0, 0, ele.width ,ele.height);
  return cnv.toDataURL('image/jpeg').substring(22);    
  """, chrome.find_element_by_xpath('你取得的 captcha xpath'))
 
with open("captcha.png", 'wb') as image:
  image.write(base64.b64decode(img_base64))

這樣就能搭配上方的 code 範本解決驗證碼的問題了


工作原理

2Captcha 用幾乎相同的兩個 API 端點解決了許多不同的CAPTCHA樣式。
第一個請求傳遞解決 CAPTCHA 所需的數據,並返回一個請求 ID。
對於基於圖像的 CAPTCHA,數據將是 CAPTCHA 本身的 base64 版本圖像。

獲得請求ID後,將需要將請求提交到結果端點,進行輪詢,直到解決方案準備就緒為止。


結論

2Captcha 真的很方便,只是比較有趣的是他們的驗證機制其實是靠大量的人工驗證才取得的XD
所以上方的 code 才會有說明到 2Captcha 服務有時無法即時辨識與回應結果 原因就是這樣
但還是要理解一下 Captcha 本身存在目的就是為了阻擋機器人
所以希望各位使用 2Captcha 時,如果只是想輔佐自己日常遇到的小問題,非常歡迎使用。

同時請秉持的友善工程的心,也可以當白帽給與對方公司改善建議

切勿使用再惡意行為

切勿使用再惡意行為

切勿使用再惡意行為

提供官方的文件

同時它也有支援其他類型的驗證碼

  • hCaptcha
  • GeeTest
  • Arkose Labs Captcha (FunCaptcha)
  • KeyCaptcha

上一篇
[Day19] [Web 自動化] Robot framework 起手式,快速安裝跟設定
下一篇
[Day21] 軟體世界裡的 TDD/BDD/ATDD!懶人包幫你一次釐清(一)
系列文
QA 三十天養成日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言