# Python

> YesCaptcha의 Python 예제예요. 잔액 조회, 이미지 캡차 인식, 재사용 가능한 클라이언트 클래스(작업 생성, 5초마다 폴링), asyncio 동시 작업 수 제어, requests와 Selenium으로 reCAPTCHA 제출까지 다뤄요.

Source: https://docs.yescaptcha.com/ko/samples/python/ · Last verified: 2026-10-15

> This page was machine-translated from the Chinese version. If anything differs, the Chinese version prevails: https://docs.yescaptcha.com/zh/samples/python/

실행 환경: Python 3.8 이상, `pip install requests`. 실행하기 전에 환경 변수를 설정하세요:

```bash
export YESCAPTCHA_CLIENT_KEY=your_client_key
```

## 잔액 조회

포인트가 차감되지 않으며, clientKey가 올바른지 확인할 때 사용해요:

get_balance.py

```python
"""Check the balance. getBalance is free and is a quick way to verify your clientKey."""
import os

import requests

CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]

r = requests.post(
    "https://api.yescaptcha.com/getBalance",
    json={"clientKey": CLIENT_KEY},
    timeout=30,
)
data = r.json()
if data.get("errorId"):
    # e.g. ERROR_KEY_DOES_NOT_EXIST when the clientKey is wrong
    print("error:", data.get("errorCode"), data.get("errorDescription"))
else:
    print("balance (points):", data["balance"])
```

## 이미지 캡차 하나 인식하기

동기 작업 유형 `ImageToTextTaskOcrBase`는 요청 한 번으로 결과를 받아요. 예제 이미지: [captcha.jpg](https://docs.yescaptcha.com/samples/captcha.jpg).

quickstart.py

```python
"""First request: read an alphanumeric image captcha with ImageToTextTaskOcrBase
(synchronous, 2 points per image).

Usage:
    export YESCAPTCHA_CLIENT_KEY=your_client_key
    python quickstart.py captcha.png
"""
import base64
import os
import sys

import requests

CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]
image_path = sys.argv[1] if len(sys.argv) > 1 else "captcha.png"

with open(image_path, "rb") as f:
    body = base64.b64encode(f.read()).decode()  # no "data:" prefix

r = requests.post(
    "https://api.yescaptcha.com/createTask",
    json={
        "clientKey": CLIENT_KEY,
        "task": {"type": "ImageToTextTaskOcrBase", "body": body},
    },
    timeout=30,
)
data = r.json()
if data.get("errorId"):
    raise SystemExit(f"{data.get('errorCode')}: {data.get('errorDescription')}")
print("text:", data["solution"]["text"])
```

## 재사용 가능한 클라이언트

아래 파일을 프로젝트에 복사하세요. 동기와 비동기 작업 유형 모두 사용할 수 있어요:

yescaptcha.py

```python
"""A small client you can copy into your project: create tasks, poll results, check the balance.

    from yescaptcha import YesCaptcha
    client = YesCaptcha(os.environ["YESCAPTCHA_CLIENT_KEY"])
    solution = client.solve({
        "type": "NoCaptchaTaskProxyless",
        "websiteURL": "https://www.google.com/recaptcha/api2/demo",
        "websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
    })
    print(solution["gRecaptchaResponse"])
"""
import os
import time

import requests

class YesCaptchaError(Exception):
    def __init__(self, code, description):
        super().__init__(f"{code}: {description}")
        self.code = code
        self.description = description

class YesCaptcha:
    def __init__(self, client_key, endpoint="https://api.yescaptcha.com", poll_interval=5, timeout=180):
        self.client_key = client_key
        self.endpoint = endpoint.rstrip("/")
        self.poll_interval = poll_interval  # 5 s: polling the same taskId more often only returns "processing"
        self.timeout = timeout
        self.session = requests.Session()

    def call(self, method, payload=None):
        body = {"clientKey": self.client_key, **(payload or {})}
        data = self.session.post(f"{self.endpoint}/{method}", json=body, timeout=30).json()
        if data.get("errorId"):
            raise YesCaptchaError(data.get("errorCode"), data.get("errorDescription"))
        return data

    def balance(self):
        return self.call("getBalance")["balance"]

    def solve(self, task):
        created = self.call("createTask", {"task": task})
        if created.get("status") == "ready":  # synchronous types return the solution directly
            return created["solution"]
        task_id = created["taskId"]
        deadline = time.time() + self.timeout
        while time.time() < deadline:
            time.sleep(self.poll_interval)
            result = self.call("getTaskResult", {"taskId": task_id})
            if result.get("status") == "ready":
                return result["solution"]
        raise TimeoutError(f"task {task_id} not ready after {self.timeout}s")

if __name__ == "__main__":
    client = YesCaptcha(os.environ["YESCAPTCHA_CLIENT_KEY"])
    print("balance:", client.balance())
```

```python
from yescaptcha import YesCaptcha

client = YesCaptcha(os.environ["YESCAPTCHA_CLIENT_KEY"])
solution = client.solve({
    "type": "HCaptchaTaskProxyless",
    "websiteURL": "https://accounts.hcaptcha.com/demo",
    "websiteKey": "a5f74b19-9e45-40e0-b45d-47ff91b7a6c2",
})
print(solution["gRecaptchaResponse"])
```

오류가 발생하면 `YesCaptchaError`가 발생하고, `e.code`가 오류 코드예요. 의미는 [오류 코드](https://docs.yescaptcha.com/ko/api/errors.md)를 참고하세요.

## 동시 작업 수 제어

작업을 일괄로 보낼 때는 동시에 처리 중인 요청 수를 제한하고, `ERROR_THREADS_MAXIMUM`을 받으면 잠시 기다렸다가 다시 시도하세요(`pip install aiohttp` 필요). 자세한 내용은 [동시 작업 수 제한과 자동 일시 중지](https://docs.yescaptcha.com/ko/api/rate-limits.md)를 참고하세요:

concurrency.py

```python
"""Limit concurrency: keep the number of requests waiting for a result below your limit, and back off
on ERROR_THREADS_MAXIMUM (rejected requests are not charged). Requires: pip install aiohttp"""
import asyncio
import os

import aiohttp

CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]
LIMIT = 15  # below your concurrency limit
sem = asyncio.Semaphore(LIMIT)

async def solve(session, task):
    async with sem:  # at most LIMIT requests in progress at a time
        result = {}
        for attempt in range(5):
            async with session.post(
                "https://api.yescaptcha.com/createTask",
                json={"clientKey": CLIENT_KEY, "task": task},
            ) as resp:
                result = await resp.json()
            if result.get("errorCode") != "ERROR_THREADS_MAXIMUM":
                return result
            await asyncio.sleep(1 + attempt)  # over the limit: wait and retry
        return result

async def main(tasks):
    async with aiohttp.ClientSession() as session:
        return await asyncio.gather(*(solve(session, t) for t in tasks))

if __name__ == "__main__":
    print(asyncio.run(main([])))
```

## reCAPTCHA 토큰 제출

-   requests로 직접 제출: [토큰으로 reCAPTCHA 완료하기](https://docs.yescaptcha.com/ko/guides/submit-recaptcha-token.md#method-1-send-the-request-yourself-recommended)를 참고하세요
-   Selenium으로 브라우저에 입력: [토큰으로 reCAPTCHA 완료하기](https://docs.yescaptcha.com/ko/guides/submit-recaptcha-token.md#method-2-fill-it-into-the-page-selenium-and-similar)를 참고하세요
-   Selenium으로 이미지 문제 클릭 시뮬레이션: [reCAPTCHA v2 이미지 인식 클릭 시뮬레이션](https://docs.yescaptcha.com/ko/guides/recaptcha-click-selenium.md), [hCaptcha 이미지 인식 클릭 시뮬레이션](https://docs.yescaptcha.com/ko/guides/hcaptcha-click-selenium.md)을 참고하세요
