Files
robotex/src/captcha/turnstile.py
T
protokeyandClaude Opus 5.5 5ed2cfbb3d feature: действие captcha value=image — капча-картинка через 2captcha (#109)
Снимок элемента картинки на текущей странице (без повторной загрузки src) уходит
в 2captcha как обычная капча (method=base64), ответ набирается в поле target
как у typing и возвращается в result действия. Необязательные подсказки:
min_len, max_len, numeric, lang, case_sensitive. Клиент: Action.captcha_image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 16:17:25 +04:00

43 lines
1.3 KiB
Python

"""
<div id="cf-turnstile" class="cf-turnstile" data-sitekey="3x00000000000000000000FF">
<div>
<div></div>
<input type="hidden" name="cf-turnstile-response" id="cf-chl-widget-a3ptc_response">
</div>
</div>
Кликабельный чекбокс Cloudflare рендерит в закрытом shadow DOM — туда лезть
не нужно и бессмысленно. sitekey и поле для ответа лежат в обычном DOM
контейнера, поэтому решаем через API 2captcha и просто подставляем токен.
"""
import logging
from .base import Captcha, Page
logger = logging.getLogger(__name__)
class SolverTurnstile(Captcha):
ctype = "cloudflare"
async def solve(self, selector, page: Page, **options):
container = page.locator(selector)
await container.wait_for()
site_key = await container.get_attribute("data-sitekey")
response_input = container.locator('input[name="cf-turnstile-response"]')
await response_input.wait_for(state="attached")
code = await self.turnstile(page.url, site_key)
await response_input.evaluate((
"(el, value) => {"
"el.value = value;"
"el.dispatchEvent(new Event('input', {bubbles: true}));"
"el.dispatchEvent(new Event('change', {bubbles: true}));"
"}"
), code)
return code