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>
This commit is contained in:
1 parent
502b6e1003
commit
5ed2cfbb3d
15 files changed
+301
-9
No files matched your search
+12
-1
@@ -100,5 +100,16 @@ async def main():
|
||||
## Действия
|
||||
|
||||
`Action.fill`, `typing`, `click`, `submit`, `mouse_move`, `delay(seconds)`, `wait_for(selector, timeout=None)`,
|
||||
`inner_html`, `inner_text`, `captcha(selector, kind)`, `pass_challenge()`. Вместо `Action` можно передать dict в формате
|
||||
`inner_html`, `inner_text`, `captcha(selector, kind)`, `captcha_image(selector, target, **hints)`, `pass_challenge()`. Вместо `Action` можно передать dict в формате
|
||||
API: `{"type": "click", "selector": "#a"}`.
|
||||
|
||||
Капча-картинка («код с картинки»): снимок элемента уходит в 2captcha, ответ набирается в поле и возвращается
|
||||
в `result`. Подсказки: `min_len`, `max_len`, `numeric` (1 — цифры, 2 — буквы), `lang`, `case_sensitive`.
|
||||
|
||||
```python
|
||||
res = s.run(actions=[
|
||||
Action.captcha_image("#popup-signup img.captcha", '#popup-signup input[name="captcha"]', min_len=4),
|
||||
Action.submit("#popup-signup button[type=submit]"),
|
||||
], captcha="<ключ 2captcha>")
|
||||
code = res.results[0]
|
||||
```
|
||||
@@ -11,6 +11,13 @@ class Action:
|
||||
selector: str | None = None
|
||||
value: str | None = None
|
||||
timeout: int | None = None
|
||||
# только для captcha_image
|
||||
target: str | None = None
|
||||
min_len: int | None = None
|
||||
max_len: int | None = None
|
||||
numeric: int | None = None
|
||||
lang: str | None = None
|
||||
case_sensitive: bool | None = None
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return {k: v for k, v in vars(self).items() if v is not None}
|
||||
@@ -60,9 +67,25 @@ class Action:
|
||||
def captcha(cls, selector: str, kind: str) -> "Action":
|
||||
"""Решить капчу через 2captcha: kind — cloudflare, recaptcha или hcaptcha; нужен параметр captcha (ключ)."""
|
||||
if kind not in CAPTCHA_TYPES:
|
||||
raise ValueError(f"captcha kind must be one of: {', '.join(CAPTCHA_TYPES)}")
|
||||
raise ValueError(f"captcha kind must be one of: {', '.join(CAPTCHA_TYPES)} (image: use captcha_image)")
|
||||
return cls("captcha", selector, kind)
|
||||
|
||||
@classmethod
|
||||
def captcha_image(
|
||||
cls, selector: str, target: str, *,
|
||||
min_len: int | None = None, max_len: int | None = None, numeric: int | None = None,
|
||||
lang: str | None = None, case_sensitive: bool | None = None,
|
||||
) -> "Action":
|
||||
"""Капча-картинка: снимок элемента selector уходит в 2captcha, ответ набирается в поле target
|
||||
и возвращается в result; нужен параметр captcha (ключ).
|
||||
|
||||
Подсказки 2captcha: min_len/max_len — 1–20 символов; numeric — 1 только цифры, 2 только буквы,
|
||||
3 цифры или буквы, 4 и цифры, и буквы; lang — код языка; case_sensitive — учитывать регистр."""
|
||||
return cls(
|
||||
"captcha", selector, "image", target=target, min_len=min_len, max_len=max_len,
|
||||
numeric=numeric, lang=lang, case_sensitive=case_sensitive,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def pass_challenge(cls) -> "Action":
|
||||
"""Пройти антибот на текущей странице (например, после submit)."""
|
||||
|
||||
Reference in new issue
Block a user