Как решить reCAPTCHA v2 в Python с помощью SDK от CapSkip

solve recaptcha v2 in python - How to Solve reCAPTCHA v2 in Python With the CapSkip SDK

reCAPTCHA v2 имеет три варианта, и в Python это одна функция с разными именованными аргументами. Checkbox сводится к простому вызову, Invisible и Enterprise задаются флагами, и оба можно указать одновременно. Python также единственный SDK CapSkip с по-настоящему отдельным асинхронным клиентом, что важно, как только вы решаете более одной капчи за раз.

Настройка

# Python 3.10 or newer.
pip install capskip

CapSkip решает капчи локально, поэтому сначала запустите десктопное приложение, а затем направьте клиент на порт из его настроек:

from capskip import CapSkip

solver = CapSkip(
    apiKey="capskip",        # any string when key validation is off
    host="127.0.0.1",
    port=8080,
    recaptchaTimeout=300,    # seconds
)

В продакшене вместо этого считывайте их из переменных окружения:

import os
from capskip import CapSkip

solver = CapSkip(
    apiKey=os.getenv("CAPSKIP_API_KEY", "capskip"),
    host=os.getenv("CAPSKIP_HOST", "127.0.0.1"),
    port=int(os.getenv("CAPSKIP_PORT", "8080")),
)

Три варианта

ВариантКлючевое слово для добавления
Checkboxнет
Invisibleinvisible=1
Enterpriseenterprise=1
Невидимая Enterpriseоба
# Checkbox: the baseline call.
result = solver.recaptcha(
    sitekey="6Lc...YOUR_SITEKEY",
    url="https://example.com/login",
)

print(result["code"])   # g-recaptcha-response token

# Invisible.
result = solver.recaptcha(sitekey=sitekey, url=page_url, invisible=1)

# Enterprise, and both together.
result = solver.recaptcha(sitekey=sitekey, url=page_url, enterprise=1)
result = solver.recaptcha(sitekey=sitekey, url=page_url, enterprise=1, invisible=1)

Возвращаемое значение представляет собой обычный dict, поэтому result["code"] это токен. Также есть result["captchaId"] если хотите логировать, какое внутреннее решение его сгенерировало.

Как правильно указать sitekey и URL

Sitekey представляет собой data-sitekey атрибут на контейнере виджета или первый аргумент для grecaptcha.render когда контейнера нет. Он всегда начинается с 6L и является публичным.

URL должен быть страницей, на которой отображается виджет. Чаще всего именно передача обработчика формы или редиректа после входа даёт токен, который решается нормально, а затем не проходит валидацию.

Отправка токена

import requests

response = requests.post(
    "https://example.com/login",
    data={
        "g-recaptcha-response": result["code"],
        "username": "...",
        "password": "...",
    },
)

Токены действуют около двух минут и одноразовые, поэтому решайте как можно позже в процессе. Если сайт передаёт токен в JavaScript-callback, а не в поле формы, решение идентично, но отправка отличается, что наш решатель callback для reCAPTCHA v2 охватывает эта страница.

Решение нескольких сразу

Именно здесь Python отличается от других SDK CapSkip. AsyncCapSkip это настоящая асинхронная реализация, а не псевдоним, поэтому она действительно распараллеливает решения:

import asyncio
from capskip import AsyncCapSkip

async def main():
    solver = AsyncCapSkip()
    r1, r2 = await asyncio.gather(
        solver.recaptcha(sitekey=key_a, url="https://a.example.com"),
        solver.recaptcha(sitekey=key_b, url="https://b.example.com"),
    )
    print(r1["code"], r2["code"])

asyncio.run(main())

В SDK для Node.js и .NET AsyncCapSkip остаётся всего лишь псевдонимом, и в PHP он существует лишь для того, чтобы перенесённый код компилировался. Только в Python переход на него действительно меняет поведение.

Ошибки

from capskip import (
    CapSkip, ValidationException, NetworkException,
    ApiException, TimeoutException,
)

try:
    result = solver.recaptcha(sitekey=sitekey, url=page_url)
except ValidationException:
    pass   # missing or malformed arguments
except NetworkException:
    pass   # CapSkip is not running
except ApiException:
    pass   # bad sitekey or pageurl
except TimeoutException:
    pass   # exceeded recaptchaTimeout

Все четыре наследуются от общей базы, поэтому except CapSkipError перехватывает всё, если вы предпочитаете обрабатывать сбои в одном месте.

Использование прокси

result = solver.recaptcha(
    sitekey=sitekey,
    url=page_url,
    proxy={"type": "HTTPS", "uri": "user:[email protected]:3128"},
)

Прокси работают для reCAPTCHA, Turnstile и GeeTest. Для графических капч они не поддерживаются, так как те решаются по байтам изображения и никогда не доходят до целевого сайта.

Часто задаваемые вопросы

Нужно ли опрашивать результат?

Нет. SDK опрашивает внутренне и возвращает готовый токен, поэтому CAPCHA_NOT_READY никогда не доходит до вашего кода. Он начинает проверять через 250 мс и снижает частоту, что обычно лучше написанного вручную цикла.

Стоит ли использовать AsyncCapSkip для одного решения?

Не особо. Это важно, когда несколько решений выполняются одновременно или когда вы уже находитесь внутри event loop и блокирующий вызов застопорит его. Для одного решения в скрипте синхронный клиент проще.

Какие версии Python поддерживаются?

3.10 и новее. У пакета нет тяжёлых зависимостей, поэтому он встраивается в существующий проект парсинга или автоматизации, не подтягивая ворох лишнего.

Сводка

Одна функция, три варианта, выбираемые с помощью invisible и enterprise. Прочитайте result["code"], отправьте его как g-recaptcha-response, и обратитесь к AsyncCapSkip когда вы решаете массово.

Более широкий набор возможностей Python находится на Решатель капчи для Python странице, другие языки на Решатель reCAPTCHA v2 страница, и есть живая демонстрация v2 для тестирования. CapSkip работает как распознавание капчи который работает на вашем собственном компьютере.