Python용 Playwright로 CAPTCHA 솔루션 제출하기

작성: solvethree읽는 데 3분

먼저 CAPTCHA를 해결한 다음, 동일한 프록시와 반환된 브라우저 식별 정보로 Playwright 컨텍스트를 생성하세요. 애플리케이션이 실제로 전송하는 필드를 통해 solution.token을 제출하세요.

아래 예제는 직접 제어하는 페이지의 폼을 제출합니다. 애플리케이션의 POST 응답을 기다리며, reCAPTCHA를 가로채거나 범용 CAPTCHA 콜백에 의존하지 않습니다.

이 페이지의 내용

대상 및 환경 준비

Python 3.10+를 사용하고, Playwright와 해당 Chromium 브라우저를 설치한 다음 공식 solvethree Python SDK wheel을 설치하세요. 워크스페이스 API 키는 브라우저 JavaScript가 아닌 Python 프로세스에 보관하세요.

  • TARGET_URL: 폼 페이지의 전체 URL입니다. 예제는 해결 요청에 사용할 호스트 이름을 이 URL에서 추출합니다.
  • SOLVETHREE_PROXY: 필요한 경우 인증 자격 증명을 포함하는 프록시 URL입니다. 해결과 브라우저 트래픽에 동일한 프록시를 사용합니다.
  • SOLVETHREE_API_KEY: 워크스페이스 API 키입니다.

대상 호스트 이름에는 워크스페이스에서 사용할 수 있는 활성 프로필이 필요합니다. 예제를 실행하기 전에 사이트 프로필을 설정하세요. 예제의 login 액션을 통합에 필요한 액션으로 변경하세요. 호스트 이름과 액션을 전송하는 것만으로는 프로필이 생성되지 않습니다. 요청은 기본적으로 reCAPTCHA Enterprise v3를 사용합니다.

해결, Chromium 구성 및 제출

Python Playwright · 실제 폼 제출
# Install playwright and the official Python SDK; run playwright install chromium.
import asyncio
import os
from urllib.parse import urlsplit, unquote
from playwright.async_api import async_playwright
from solvethree import Solvethree

async def main():
    target = os.environ["TARGET_URL"]
    proxy = urlsplit(os.environ["SOLVETHREE_PROXY"])
    client = Solvethree(os.environ["SOLVETHREE_API_KEY"])
    task = {"site": urlsplit(target).hostname, "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"]}
    result = await asyncio.to_thread(client.solve, task, timeout=180)
    solution = result["solution"]
    async with async_playwright() as playwright:
        browser = await playwright.chromium.launch()
        try:
            netloc = proxy.netloc.rsplit("@", 1)[-1]
            context = await browser.new_context(
                proxy={"server": f"{proxy.scheme}://{netloc}", "username": unquote(proxy.username or ""), "password": unquote(proxy.password or "")},
                user_agent=solution["userAgent"], extra_http_headers={"sec-ch-ua": solution["secChUa"]})
            page = await context.new_page()
            await page.goto(target)
            field = page.locator('[name="g-recaptcha-response"]')
            await field.wait_for(state="attached")
            await field.evaluate("(field, token) => { field.value=token; field.dispatchEvent(new Event('input',{bubbles:true})); }", solution["token"])
            async with page.expect_response(lambda r: r.request.method == "POST" and urlsplit(r.url).netloc == urlsplit(target).netloc) as outcome:
                await page.get_by_role("button", name="Submit", exact=True).click()
            print("Application HTTP status:", (await outcome.value).status)
            # Check the application's actual response; adapt form/CSRF/session setup.
            await context.close()
        finally:
            await browser.close()

asyncio.run(main())

Solvethree는 동기식입니다. asyncio.to_thread를 통해 client.solve를 호출하면 생성 및 폴링 작업이 Playwright의 이벤트 루프를 차단하지 않습니다. 이 호출은 준비된 결과를 반환하거나 예외를 발생시킵니다. SDK에는 네이티브 비동기 클라이언트가 없습니다.

브라우저 컨텍스트는 solution.userAgent와 solution.secChUa를 사용합니다. 또한 이 예제는 프록시 서버를 사용자 이름 및 비밀번호와 분리하고, 자격 증명을 디코딩한 후 Playwright에 전달합니다. 이 작업은 프록시 하나를 사용하므로 후보 선택 단계가 없습니다.

  1. 1.

    애플리케이션의 토큰 입력에 맞추기

    이 예제는 필드가 연결될 때까지 기다린 후 solution.token을 할당하고 input 이벤트를 발생시킵니다. 필드가 화면에 표시될 필요는 없습니다. 애플리케이션이 다른 필드를 제출하거나 다른 곳에서 토큰 상태를 읽는다면, 발신 요청에 맞게 이 전달 과정을 조정하세요.

  2. 2.

    폼의 세션 요구 사항 추가

    이 예제는 새 브라우저 컨텍스트에서 시작합니다. 제출하기 전에 애플리케이션에 필요한 세션, 폼 준비 또는 CSRF 처리를 추가하세요.

  3. 3.

    올바른 POST 기다리기

    Submit을 클릭하기 전에 응답 대기를 등록합니다. 해당 조건식은 대상 URL의 네트워크 위치로 전송되는 POST와 일치합니다. 페이지가 같은 위치로 다른 POST 요청도 보낸다면, 조건식을 제출 엔드포인트로 한정하세요.

애플리케이션 응답 확인

출력된 HTTP 상태는 일치하는 응답이 도착했음을 확인해 줍니다. 제출이 수락되었는지 판단하려면 애플리케이션의 응답 본문이나 이후 페이지 상태를 확인하세요. solvethree 작업이 준비되었다는 것은 솔루션이 생성되었다는 뜻이지, 대상이 이를 수락했다는 뜻은 아닙니다.

애플리케이션이 준비된 토큰을 거부합니다.

다른 해결 작업에 비용을 지불하기 전에 발신 폼 요청을 확인하세요.

다음을 시도해 보세요: 작업 ID나 이전 값이 아닌 solution.token이 포함되어 있는지 확인하세요. 제출 시 해결에 사용한 프록시, 반환된 사용자 에이전트와 클라이언트 힌트, 의도한 대상을 사용하는지 확인하세요.

응답 대기에서 무관한 요청이 포착됩니다.

포착된 POST URL과 실제 폼 엔드포인트를 비교하세요.

다음을 시도해 보세요: 동일한 네트워크 위치의 모든 POST와 일치하도록 하지 말고, 응답 조건식을 해당 엔드포인트로 한정하세요.

브라우저 제출 전에 solve 호출에서 예외가 발생합니다.

HTTP 요청 오류와 최종 실패 상태의 작업을 구분하세요.

다음을 시도해 보세요: 성공이 아닌 HTTP 응답은 별도로 처리하세요. 실패한 작업은 errorCode와 error를 확인하고, 입력을 그대로 재시도하지 말고 원인을 해결하세요. SDK의 solve 메서드는 이미 실패 시 중단됩니다.

첫 작업을 실행하세요.

워크스페이스 크레딧 $5로 시작하세요.

워크스페이스 만들기
Python용 Playwright로 CAPTCHA 솔루션 제출하기 · solvethree