diff --git a/Makefile b/Makefile index b587c1b..1bda020 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,8 @@ export DEV_RABBITMQ_PORT DEV_REDIS_PORT DEV_POSTGRES_PORT RABBITMQ_PASSWORD POST DEV_ENV := RABBITMQ_URL=amqp://robotex:$(RABBITMQ_PASSWORD)@localhost:$(DEV_RABBITMQ_PORT)/ \ REDIS_URL=redis://localhost:$(DEV_REDIS_PORT)/0 \ DATABASE_URL=postgresql+asyncpg://robotex:$(POSTGRES_PASSWORD)@localhost:$(DEV_POSTGRES_PORT)/robotex \ - BROWSER_SLOTS=$(DEV_SLOTS) + BROWSER_SLOTS=$(DEV_SLOTS) \ + LOG_LEVEL=DEBUG help: @echo "make install [ ...] - установить пакет(ы) в $(VENV), обновить $(REQUIREMENTS), собрать wheel в $(WHEELS_DIR)/" diff --git a/src/antibot/known_providers/recaptcha.py b/src/antibot/known_providers/recaptcha.py index 908fe0e..c8e1519 100644 --- a/src/antibot/known_providers/recaptcha.py +++ b/src/antibot/known_providers/recaptcha.py @@ -1,4 +1,3 @@ -import json import logging from patchright.async_api import Page @@ -6,7 +5,7 @@ from patchright.async_api import Page from captcha.base import Captcha from ..base import Detector, ChallengeInfo, Solver, AntiBotProvider, click_and_race -from ..base import Stage +from ..base import Stage, PWTimeoutError from ..registry import register from ..exceptions import IframeLoadError @@ -56,8 +55,8 @@ class ReCaptchaSolver(Solver): self.captcha_solver: Captcha = self._opt["captcha_solver"] async def form_submit(self, token: str) -> bool: - # noinspection UnnecessaryLabelJS - return await self.page.evaluate(f"mw:({JS_CHALLENGE_SUBMIT})({json.dumps(token)})") + # ___grecaptcha_cfg живёт в основном мире страницы, а patchright по умолчанию выполняет скрипт в изолированном + return await self.page.evaluate(JS_CHALLENGE_SUBMIT, token, isolated_context=False) async def solve(self, page: Page, info: ChallengeInfo): self.page = page @@ -76,9 +75,15 @@ class ReCaptchaSolver(Solver): return else: log.debug("Нужно решать капчу. Закрою окошко с картинками.") + # полупрозрачная подложка на весь экран (position: fixed), клик по ней закрывает окно. В её центре лежит + # само окно с картинками и перехватывает клик — поэтому кликаем в угол element = page.locator("xpath=//div[@class='g-recaptcha-bubble-arrow']/../div[1]") if await element.is_visible(): - await element.click() + try: + await element.click(position={"x": 1, "y": 1}, timeout=5_000) + except PWTimeoutError: + # не закрылось — не страшно, токен уходит через callback + log.debug("Окошко с картинками закрыть не удалось") log.debug("Решаем капчу...") assert info.detect_locator diff --git a/src/captcha/base.py b/src/captcha/base.py index 3b19ed0..4704769 100644 --- a/src/captcha/base.py +++ b/src/captcha/base.py @@ -30,6 +30,7 @@ class Captcha: return resp async def turnstile(self, url, site_key): + # TODO: not finished! resp = await self._run(self._solver.turnstile, site_key, url) return resp diff --git a/src/worker/actors.py b/src/worker/actors.py index 04f0d02..759c4b8 100644 --- a/src/worker/actors.py +++ b/src/worker/actors.py @@ -10,10 +10,13 @@ import logging import os import socket +LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper() logging.basicConfig( - level=os.getenv("LOG_LEVEL", "INFO").upper(), + level=LOG_LEVEL, format="%(asctime)s %(levelname)s %(name)s: %(message)s", ) +# под dramatiq логирование уже настроено им самим (уровень INFO) и basicConfig ничего не делает — уровень явно +logging.getLogger().setLevel(LOG_LEVEL) import dramatiq # noqa: E402 from dramatiq.asyncio import get_event_loop_thread # noqa: E402 diff --git a/tests/test_main.http b/tests/test_main.http index d36f82b..2e7cff2 100644 --- a/tests/test_main.http +++ b/tests/test_main.http @@ -147,18 +147,14 @@ X-API-Key: {{api_key}} "url": "https://lessons.zennolab.com/captchas/recaptcha/v2_nosubmit.php?level=low", "proxy": "{{proxy}}", "actions": [ - { - "type": "pass_challenge", - "value": "recaptcha" - }, { "type": "inner_text", - "selector": "//button[contains(@class, 'actionItem_151') and @type='submit']" + "selector": "//div[@id='main']/div/h2" } ], "captcha": "{{captcha_key}}", "captcha_type": "recaptcha", - "captcha_success_locator": "//code[contains(@class, 'hljs _successMessageCode')]" + "captcha_success_locator": "//div[@id='main']" } ###