用 2칼로리 센서스通過 인증 코드人機驗證
在介紹 2칼로리 센서스前,先簡單的認識一下 인증 코드
인증 코드
인증 코드全稱是"컴퓨터와 인간을 구분하는 완전 자동화된 공공 그래픽 테스트"翻譯成華文是超級繞口的「全自動區分電腦和人類的公開圖靈測試」,這串無敵長的文字簡單講就是人機驗證,인증 코드人機驗證存在的目的通常是為了遏止網站被外部的程式惡意的大量操作,然而這樣的機制也擋住了我們家從事無害工作的可愛小爬蟲 🐛 或小機器人 🤖,所以我輩開發者就需要像 2칼로리 센서스這樣的服務幫我們通過那 인증 코드考驗.
常見的 인증 코드
在台灣常見到的 인증 코드的場合大概有這些:
台灣高鐵
台灣高鐵的 인증 코드是較為傳統的文字混淆型:
 
 臺灣鐵路
臺鐵的則是用 구글的 다시 설명:
 
 網路銀行
除了訂票外,網銀也很常看到 인증번호:
 
 特別要說明的是,上面的舉例僅是用於說明 인증 코드的使用場景,請不要動搶票的歪腦筋,那有可能是違法的,請諮詢專業法律人士獲得正確的法律知識,也歡迎留言共同討論.
2칼로리 센서스
 
 來源: 2Captcha
先簡單認識 2Captcha ,做為一個辨識 인증 코드的服務,2칼로리 센서스背後的辨識機制其實是由人工完成的,我們傳送給 2칼로리 센서스的圖片,都會轉送給分散在全世界的 2칼로리 일꾼們,經過人工辨識後再把結果回傳,而那些辛苦的 노동자.們也可以透過 2칼로리 센서스的仲介機制獲得報酬,因為是人工辨識,所以我們可以預期:
2칼로리 센서스的收費
在費用方面,2칼로리 센서스是採用動態計價,動態的基準是當前 2칼로리 센서스與 노동자.們的工作負荷,當負荷量大時會升價、負荷量小時會降價,當前的費率會顯示在 Statistics 頁面,例如下面是本文撰寫時的費率:
 
 上圖可以看到,普通的 인증 코드每一千個收費僅 0.74美金,而較難的 레파차每一千個則收費 2.99美金,相較於自行開發各種花式 인공지능辨識系統所要花費的人力物力,2칼로리 센서스算是相當低廉的價格了.
在 통계적頁面,除了費率外,還有目前 2칼로리 센서스服務的負載程度,以及解題的速度,上圖顯示一般的 인증 코드花 15秒,而 레파차要花 46秒,儘管與 2칼로리 센서스文件內的 5秒、20秒有差距,看起來還在可以接受的程度內.
在簡單的認識 2칼로리 센서스的機制與收費之後,下面就來實際玩玩看 2칼로리 센서스吧!
2칼로리 센서스辨識一般 인증 코드
在這個範例中,我們會示範用 극작가登入一個網站,並且用 2Captcha 協助我們辨識登入時的 인증 코드驗證碼.
事前準備
在開始前簡單的介紹一下 극작가是微軟開發的瀏覽器自動化套件,類似於陳年的 셀렌的優點有:
在 2칼로리 센서스方面,開立帳號後,登入可以看到 2Captcha API 키:
 
 這組 API 키用於與 2칼로리 센서스程式交互,下面的範例程式中的 API 키是無效的,請務必換成您個人的 API 키
登入與 인증 코드辨識
回到範例的主題上,下面我們會用 파이썬 극작가以及 2Captcha 的 Python 套件 ,示範通過下面這個登入頁面:
 
 在這個典型的登入表單中,我們的腳本會用 극작가輸入帳密,並且把那 인증 코드圖片透過 2Captcha API取得驗證碼,最後點按「登入」:
import base64
from playwright.sync_api import sync_playwright
from twocaptcha import TwoCaptcha
CAPTCHA_API_KEY = '5c0f7e0306aa2e0398510ef9ce6dbca'
solver = TwoCaptcha(apiKey=CAPTCHA_API_KEY)
def solve(image):
  try:
    result = solver.normal(
      file=image,
      numeric=4,
      minLength=4,
      maxLength=4,
      caseSensitive=1
    )
  except Exception as e:
    print(e)
  print(result)
  return result
def report(captcha_id: str, success: bool):
  solver.report(captcha_id, success)
def main():
  while True:
    with sync_playwright() as p:
      browser = p.firefox.launch(headless=False, slow_mo=500)
      context = browser.new_context()
      page = context.new_page()
      page.goto("http://www.twoas.idv.tw/user.php")
      page.type("input[name=username]", "RSOB")
      page.type("input[name=password]", "RSOBPassword")  
      screenshot_bytes = page.locator("img[alt=captcha]").screenshot()
      captcha_image = base64.b64encode(s=screenshot_bytes).decode('utf-8')
      result = solve(image=captcha_image)
      page.type("input[name=captcha]", result['code'])
      page.click("text=立即登入")
      login_message = page.text_content("div.tips")
      try:
        assert login_message == "登入成功"
      except AssertionError as e:
        report(result['captchaId'], False)
        continue
      report(result['captchaId'], True)
      page.pause()
      context.close()
      browser.close()
      break
if __name__ == '__main__':
  main()
극작가的部份,我們用
page  物件操控大多數的瀏覽器行為,相信即使是對 극작가不熟悉的朋友也可以望文生義:goto()  函式前往指定網址. type()  函式找到特定元素,並輸入字元. locator()  函式找到元素並操控它. screenshot()  函式對元素截圖. click()  函式點按特定元素. screenshot()  取得 인증 코드圖片後,用  base64  模組轉換成 Base64編碼,交給  solve()  函式處理.在 인증 코드辨識部份,此網站的 인증 코드如下例:
 
 這是一種相對普通的 인증 코드在 2칼로리 센서스的分類上,屬於 정상이었어型.
在 2칼로리 센서스的部份,先定義一個 2칼로리 센서스的
solver  物件,並用下面的敘述得到辨識後的文字:result = solver.normal(
  file=image,
  numeric=4,
  minLength=4,
  maxLength=4,
  caseSensitive=1
)
normal()  函式,函式內的參數,除了  file  是必填,其他都是可選用的:file  可接受一個經 Base64編碼的 인증 코드圖片物件,也可以是本地的圖片檔案,或圖片的 웹 주소numeric 인증번호的字元型態, 4  表示會有字母與數字,其他的定義請參閱  2Captcha API 文件 . minLength  最小字元長度,以此例而言,都是固定四個字元. maxLength  最大字元長度,以此例而言,都是固定四個字元. caseSensitive  設為  1  表示區分大小寫. result , result  是一個結構如下的 딕트物件:{'captchaId': '69475003267', 'code': '4QR5'}
cpatchaId  是 2Captcha API賦予的交互 신분증,而  code  當然就是辨識後的答案啦!回饋辨識與否
取得
result['code']  後,填入表單,若正確登入,我們用  report()  回饋成功紀錄給 2칼로리 센서스並在最後的  break  語句完全結束  while  迴圈.反之若是失敗,則用
report()  回饋失敗紀錄給 2칼로리 센서스並在後續的  continue  語句中斷這次的  while  迴圈,進入下一個  while  迴圈,藉此做出重試的效果.成果
最後的成果可以參考這個影片:
用 2칼로리 센서스通過 레파차
完成前一個較簡單的例子後,我們來玩玩看如何用 2Captcha 通過難一點的 레파차也就是那著名的靈魂考驗「我不是機器人」:
 
 來源:網路
要用 2칼로리 센서스通過 레파차的「我不是機器人」考驗,必須先取得目標頁面的 사이트 키在原始碼裡面就可以找到這把公開的 사이트 키:
 
 有了 사이트 키之後,就可以依樣畫葫蘆,呼叫 2Captcha API得到 레파차的通關密語.
與 2칼로리 센서스交互的部份改成這樣:
result = solver.recaptcha(
  sitekey='6LflqMEUAAAAAANhC6kkXmSLiBOLiLFsHw_anYWZ',
  url="https://naweeklytimes.com/login-2/",
  version="v2",
)
{'captchaId': '69482081140', 'code': '03AGdBq252s4QsHsrr9CqzkkswdnHsUPLXIcE4OI1pEX4FUP9rNY8p760yLBsd9goaMn61vw95x981lU0...'}
code  填入一個名為  g-recaptcha-response  的文字框,然而這個文字框是隱藏的,所以得先用 극작가跑一小段 JS讓它顯示出來:page.eval_on_selector(
  selector="textarea[name=g-recaptcha-response]",
  expression="(el) => el.style.display = 'inline-block'",
)
el  就是來自  selector  抓到的元素.文字框顯示出來會像這樣:
 
 然後就比照第一個範例,帳號、密碼、레파차通關密語填一填,就可以成功登入囉!
成果
完整的程式碼如下:
from playwright.sync_api import sync_playwright
from twocaptcha import TwoCaptcha
URL = "https://naweeklytimes.com/login-2/"
SITEKEY = '6LflqMEUAAAAAANhC6kkXmSLiBOLiLFsHw_anYWZ'
CAPTCHA_API_KEY = '5c0f7e0306aa2e0398510ef9ce6dbca'
solver = TwoCaptcha(apiKey=CAPTCHA_API_KEY)
def solve(url: str):
  try:
    result = solver.recaptcha(
      sitekey=SITEKEY,
      url=url,
      version="v2",
    )
  except Exception as e:
    print(e)
    raise Exception
  print(result)
  return result
def report(captcha_id: str, success: bool):
  solver.report(captcha_id, success)
def main():
  while True:
    with sync_playwright() as p:
      browser = p.firefox.launch(headless=False, slow_mo=500)
      context = browser.new_context()
      page = context.new_page()
      page.goto(URL)
      page.type("input[name=log]", "RSOB")
      page.type("input[name=pwd]", "RSOBPassword")
      try:
        result = solve(url=URL)
      except Exception as e:
        continue
      page.eval_on_selector(
        selector="textarea[name=g-recaptcha-response]",
        expression="(el) => el.style.display = 'inline-block'",
      )
      textarea = page.locator("textarea[name=g-recaptcha-response]")
      textarea.fill(result['code'])
      page.click("input[type=submit]")
      try:
        assert page.url == "https://naweeklytimes.com/"
      except AssertionError as e:
        report(result['captchaId'], False)
        continue
      report(result['captchaId'], True)
      page.pause()
      context.close()
      browser.close()
      break
if __name__ == '__main__':
  main()
下面是執行的影片:
結語
本文我們示範用 2Captcha 通過普通的 인증 코드及 레파차在這兩種最常見的 인증 코드外,2칼로리 센서스還支援其他各式各樣的 인증 코드形式眾多,可以參考 2Captcha 的文件 與 demo 頁.
在 미국 석유 학회方面,2칼로리 센서스有提供封裝好的 Python、GO、PHP、Java、C#、C++套件,即使是沒有現成套件的語言,直接呼叫 2Captcha API也不是太困難的事.
至於 2칼로리 센서스的費用,除了真的很便宜的費率外,在設計 로봇 프로그램時,只要保留住登入後的 과자 과자或 로컬 스토리지即可省下每次都要重新登入的時間以及 인증 코드的費用,以 극작가為例,它就有 reuse authentication state 的機制,可以多加利用.
參考資料
Reference
이 문제에 관하여(用 2칼로리 센서스通過 인증 코드人機驗證), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/leon0824/yong-2captcha-tong-guo-captcha-ren-ji-yan-zheng-5f72텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)