diff --git a/Dockerfile b/Dockerfile index e4ede94..0289ed7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,8 @@ FROM mcr.microsoft.com/playwright/python:v1.49.0-noble # Видеокодеки и мультимедийные библиотеки для воспроизведения видео в Chrome RUN apt-get update && apt-get install -y \ socat \ + wget \ + unzip \ libgstreamer1.0-0 \ gstreamer1.0-plugins-base \ gstreamer1.0-plugins-good \ @@ -49,6 +51,11 @@ COPY app.py . # Создаем директорию для данных браузера RUN mkdir -p /app/browser-data && chmod 777 /app/browser-data +# Скачиваем и распаковываем CapSolver расширение для автоматического решения капчи +RUN wget -q https://github.com/capsolver/capsolver-browser-extension/releases/download/v.1.17.0/capsolver-extension.zip -O /tmp/capsolver.zip && \ + unzip -q /tmp/capsolver.zip -d /app/capsolver-extension && \ + rm /tmp/capsolver.zip + EXPOSE 8383 EXPOSE 9222 diff --git a/app.py b/app.py index c661283..13e7084 100644 --- a/app.py +++ b/app.py @@ -61,6 +61,24 @@ logger.info(f"RECAPTCHA_BYPASS: {RECAPTCHA_BYPASS}") logger.info(f"AUTO_SOLVE_CAPTCHA: {AUTO_SOLVE_CAPTCHA}") logger.info(f"===========================") +# Настраиваем CapSolver расширение с API ключом +if CAPSOLVER_API_KEY: + capsolver_config_path = "/app/capsolver-extension/assets/config.js" + if os.path.exists(capsolver_config_path): + try: + with open(capsolver_config_path, 'r') as f: + config_content = f.read() + # Заменяем apiKey на реальный + import re + config_content = re.sub(r'apiKey:\s*"[^"]*"', f'apiKey: "{CAPSOLVER_API_KEY}"', config_content) + with open(capsolver_config_path, 'w') as f: + f.write(config_content) + logger.info("CapSolver API key configured in extension") + except Exception as e: + logger.warning(f"Failed to configure CapSolver API key: {e}") + else: + logger.warning(f"CapSolver config not found at {capsolver_config_path}") + # Создаём Tools с кастомными действиями try: from browser_use import Tools, BrowserSession @@ -830,11 +848,20 @@ async def run_browser_task(task_id: str, task: str, max_steps: int, model: str): "--enable-webgpu", "--enable-webgpu-developer-features", "--use-angle=swiftshader", - # Отключено: stealth-расширение вызывает ошибки и ломает Cloudflare Turnstile - # "--load-extension=/app/stealth-extension", - # "--disable-extensions-except=/app/stealth-extension", ]) + # Добавляем расширение CapSolver для автоматического решения капчи + if AUTO_SOLVE_CAPTCHA and CAPSOLVER_API_KEY: + capsolver_ext_path = "/app/capsolver-extension" + if os.path.exists(capsolver_ext_path): + chrome_cmd.extend([ + f"--disable-extensions-except={capsolver_ext_path}", + f"--load-extension={capsolver_ext_path}", + ]) + logger.info(f"[{task_id}] CapSolver extension enabled") + else: + logger.warning(f"[{task_id}] CapSolver extension not found at {capsolver_ext_path}") + # Добавляем специальные флаги для обхода reCAPTCHA если включено if RECAPTCHA_BYPASS: chrome_cmd.extend([ @@ -848,6 +875,14 @@ async def run_browser_task(task_id: str, task: str, max_steps: int, model: str): "--disable-ipc-flooding-protection", ]) logger.info(f"[{task_id}] Added reCAPTCHA bypass flags") + else: + # Всегда добавляем --no-sandbox для работы в контейнере + # и --disable-blink-features=AutomationControlled для обхода Cloudflare Turnstile + chrome_cmd.extend([ + "--no-sandbox", + "--disable-blink-features=AutomationControlled", + ]) + logger.info(f"[{task_id}] Added minimal stealth flags for Cloudflare Turnstile") # Добавляем прокси если есть chrome_cmd.extend(proxy_args) @@ -941,11 +976,17 @@ async def run_browser_task(task_id: str, task: str, max_steps: int, model: str): browser = Browser(cdp_url=cdp_url) else: # Обычный запуск + # Всегда добавляем флаги для обхода Cloudflare Turnstile + extra_chromium_args = [ + "--no-sandbox", + "--disable-blink-features=AutomationControlled", + ] browser_profile = BrowserProfile( user_data_dir="/app/browser-data/main_profile", profile_directory="Default", headless=False, # Всегда false для поддержки reCAPTCHA keep_alive=True, + extra_chromium_args=extra_chromium_args, ) browser = Browser(browser_profile=browser_profile)