콘텐츠로 이동
서비스 상태대시보드

가이드

hCaptcha 이미지 인식 클릭 시뮬레이션(Selenium)

이 페이지는 중국어 버전을 기계 번역한 것이라 부정확한 내용이 있을 수 있어요. 중국어 버전을 기준으로 해 주세요.

이 튜토리얼은 Selenium 4로 hCaptcha 데모 페이지를 열고, 실제 브라우저에서 3×3 그리드 이미지 문제를 풀어요. 질문과 이미지 9장을 읽은 뒤 hCaptcha 이미지 인식(HCaptchaClassification)에 보내 어떤 칸이 목표인지 판단하게 하고, 그 칸을 클릭해요.

hCaptcha에는 “지정한 위치 클릭”, “드래그” 같은 문제 유형도 있어요. 이런 유형은 칸이 아니라 좌표를 반환해요. 처리 방법은 hCaptcha 이미지 인식을 참고하세요. 코드를 작성하고 싶지 않다면 브라우저 확장 프로그램을 바로 사용하세요. 이 문제 유형을 모두 지원해요.

pip install requests selenium
export YESCAPTCHA_CLIENT_KEY=your_client_key
  1. 체크박스를 클릭해요. 체크박스는 주소에 frame=checkbox가 포함된 hCaptcha iframe 안에 있어요. 해당 iframe으로 전환한 뒤 #checkbox를 클릭하세요.
  2. 문제 iframe으로 전환해요. 문제는 주소에 frame=challenge가 포함된 iframe 안에 있어요.
  3. 질문을 읽어요. .prompt-text의 텍스트가 질문이에요. 그대로 API에 전달하세요(hCaptcha 인터페이스 언어를 영어 또는 중국어 간체로 바꾸는 것을 권장해요). 질문 옆에 예시 이미지가 있으면 그 이미지도 anchors에 넣으세요.
  4. 이미지를 가져와요. 각 칸 .task-image .image의 배경 이미지가 이미지 한 장이에요. 순서대로 다운로드해 Base64로 변환하고 queries 목록을 만드세요.
  5. 인식해요. createTask를 호출하고 유형은 HCaptchaClassification으로 지정하세요. 반환된 objects는 칸과 하나씩 대응하고, true인 칸이 목표예요.
  6. 클릭하고 제출해요. 목표인 칸을 클릭하고 제출 버튼을 누르세요. 여러 라운드가 연속으로 나올 수 있으니 3~6단계를 반복하세요.
  7. 완료해요. 통과하면 페이지의 h-captcha-response 필드에 토큰이 들어가요. 이 토큰을 폼과 함께 제출하세요.
hcaptcha_click_selenium.py
"""Click through an hCaptcha 3x3 image challenge with Selenium 4 and HCaptchaClassification.
Flow: open the page -> click the checkbox -> read the question and the 9 images ->
ask YesCaptcha which images match -> click them -> submit. Repeat while new rounds appear.
Run: pip install requests selenium
export YESCAPTCHA_CLIENT_KEY=your_client_key
python hcaptcha_click_selenium.py
Each recognized round is charged (see the price list; rounds with no target found are free).
hCaptcha changes its page structure often; adjust the selectors below if a step stops working.
Click and drag questions return coordinates instead; see the HCaptchaClassification page.
"""
import base64
import os
import re
import time
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]
PAGE_URL = "https://accounts.hcaptcha.com/demo"
def classify(question, images_b64):
task = {"type": "HCaptchaClassification", "question": question, "queries": images_b64}
data = requests.post(
"https://api.yescaptcha.com/createTask",
json={"clientKey": CLIENT_KEY, "task": task},
timeout=60,
).json()
if data.get("errorId"):
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data["solution"] # synchronous
def background_image_b64(element):
"""The tiles are <div>s with a CSS background image; download it and Base64-encode it."""
style = element.get_attribute("style") or ""
match = re.search(r'url\("?(.*?)"?\)', style)
if not match:
return None
return base64.b64encode(requests.get(match.group(1), timeout=30).content).decode()
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 15)
try:
driver.get(PAGE_URL)
# 1. Click the checkbox (inside the first hCaptcha iframe)
wait.until(EC.frame_to_be_available_and_switch_to_it(
(By.CSS_SELECTOR, 'iframe[src*="hcaptcha"][src*="frame=checkbox"]')))
wait.until(EC.element_to_be_clickable((By.ID, "checkbox"))).click()
driver.switch_to.default_content()
# 2. Solve rounds in the challenge iframe
wait.until(EC.frame_to_be_available_and_switch_to_it(
(By.CSS_SELECTOR, 'iframe[src*="hcaptcha"][src*="frame=challenge"]')))
for _ in range(5):
question = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".prompt-text"))).text.strip()
tiles = driver.find_elements(By.CSS_SELECTOR, ".task-image")
images = [background_image_b64(t.find_element(By.CSS_SELECTOR, ".image")) for t in tiles]
if not tiles or None in images:
print("not a 3x3 image challenge; see the docs for click/drag questions")
break
solution = classify(question, images)
for tile, hit in zip(tiles, solution.get("objects", [])):
if hit:
tile.click()
time.sleep(0.3)
driver.find_element(By.CSS_SELECTOR, ".button-submit").click()
time.sleep(3)
if not driver.find_elements(By.CSS_SELECTOR, ".task-image"):
break
driver.switch_to.default_content()
token = driver.find_element(By.NAME, "h-captcha-response").get_attribute("value")
print("token received" if token else "not passed")
finally:
driver.quit()
  • hCaptcha의 페이지 구조는 자주 바뀌어요. 코드의 선택자가 동작하지 않으면 실제 페이지에 맞게 조정하세요.
  • 라운드마다 포인트가 차감돼요. 목표를 인식하지 못한 라운드는 차감되지 않아요. 클릭 후 검증에 실패했다면 1시간 이내에 신고해서 포인트 환불을 신청할 수 있어요.
  • 새로운 질문에서 ERROR_UNKNOWN_QUESTION이 반환되면 새로고침해서 다른 문제를 받거나 고객 지원에 문의하세요.