Другое

Как подключиться к существующему сеансу Camoufox

Настройка Camoufox для многократных подключений через WebSocket. Сохранение сессий cookies и localStorage между скриптами.

Как подключиться к существующему сеансу браузера Camoufox вместо создания нового?

Я пытаюсь автоматизировать работу с сайтом, используя библиотеку Camoufox. Вот что я делаю:

  1. Запускаю Camoufox браузер через Python/Playwright на определенном порту:
python
for i, (port, path, name) in enumerate(zip(config["ports"], config["paths"], config["names"])):
    # Создаем поток сервера
    server_thread = threading.Thread(target=run_server, args=(port, path))
    servers.append(server_thread)
    
    # Создаем поток автоматизации браузера
    browser_url = f"ws://localhost:{port}/{path}"
    browser_thread = threading.Thread(
        target=automate_browser, 
        args=(browser_url, name)
    )
    browser_automations.append(browser_thread)
    
    # Запускаем все серверы с задержками
    print(f"Запускаем {len(servers)} серверов...")
    for i, server in enumerate(servers):
        print(f"Запускаем сервер {i+1} на порту {config['ports'][i]}...")
        server.start()
        time.sleep(config["server_settings"]["start_delay"])
    
    print("Все серверы запущены. Запускаем автоматизацию браузера...")
    
    # Запускаем все автоматизации браузера с задержками
    for i, browser_automation in enumerate(browser_automations):
        browser_automation.start()
        if i < len(browser_automations) - 1:  # Не засыпаем после последней
            time.sleep(config["server_settings"]["browser_delay"])

URL браузера будет выглядеть так: ws://localhost:2525/browser2525, где 2525 - это порт для последующего подключения.

  1. Я вручную вхожу в Google и Midjourney (на основе аккаунта Google), и этот браузер Camoufox должен оставаться работающим долгое время, чтобы другие скрипты могли подключаться к нему.

  2. Затем я пытаюсь подключиться к открытому браузеру из другого скрипта:

python
async def connect_to_session(self, port): 
    if not await self.check_camoufox_availability(port):
        raise Exception(f"Порт WebSocket Camoufox {port} недоступен")
    
    ws_url = f"ws://localhost:{port}/browser{port}"
    
    browser = await self.playwright.firefox.connect(ws_url)

URL WebSocket идентичен browser_url в коде пункта 1.

Однако при выполнении кода Playwright не подключается к существующему браузеру, а запускает новый, соответственно без контекста, пустой…

Camoufox - это скрытый, кастомизированный браузер Firefox, разработанный специально для веб-скрапинга и обхода обнаружения ботов.

Чтобы подключиться к существующему сеансу браузера Camoufox вместо создания нового, вам нужно использовать правильные методы WebSocket-подключения и настройки постоянного контекста. Camoufox поддерживает подключение к существующим браузерным экземплярам через WebSocket, но требует корректной конфигурации сервера и правильного формата URL.

Содержание

Основные методы подключения к существующему сеансу

Camoufox предоставляет два основных способа подключения к существующему браузерному экземпляру:

1. Использование встроенного сервера Camoufox

Camoufox имеет встроенный сервер, который позволяет подключаться к существующим браузерным экземплярам через WebSocket. Для этого нужно правильно запустить сервер с указанием параметров постоянного контекста.

Ключевые моменты:

  • Сервер должен быть запущен с параметром reuse_existing=True
  • Используйте правильный формат WebSocket URL: ws://localhost:порт/путь
  • Убедитесь, что сервер не перезапускается при каждом подключении

2. Подключение через Playwright API

Playwright предоставляет метод connect() для подключения к существующему браузеру через WebSocket. Однако для Camoufox это требует специальной настройки, так как стандартные методы могут не работать с кастомными браузерами.

Важно: Camoufox основан на Firefox, поэтому используйте playwright.firefox.connect() вместо playwright.chromium.connect().

Настройка сервера Camoufox для многократных подключений

Ваш текущий подход не работает, потому что сервер Camoufox не настроен на повторное использование существующих экземпляров. Вот исправленная конфигурация:

python
from camoufox.server import launch_server
from camoufox import launch
import threading
import time

def run_server(port, path, reuse=True):
    """Запускаем сервер Camoufox с возможностью повторного использования"""
    server = launch_server(
        headless=False,  # Для отладки можно использовать False
        port=port,
        ws_path=path,
        reuse_existing=reuse  # Ключевой параметр!
    )
    return server

def launch_camoufox_instance(port, path):
    """Запускаем экземпляр Camoufox"""
    browser = launch(
        headless=False,
        port=port,
        ws_path=path,
    )
    return browser

Правильная последовательность действий:

  1. Сначала запустите сервер Camoufox:
python
# Запускаем сервер один раз
server_thread = threading.Thread(
    target=run_server, 
    args=(2525, "browser2525", True)
)
server_thread.start()
time.sleep(2)  # Даем время на запуск сервера
  1. Затем запустите браузерный экземпляр:
python
# Запускаем браузерный экземпляр
browser_thread = threading.Thread(
    target=launch_camoufox_instance,
    args=(2525, "browser2525")
)
browser_thread.start()
time.sleep(5)  # Даем время на запуск браузера
  1. Подключайтесь из других скриптов:
python
async def connect_to_existing_session(port, path):
    """Подключаемся к существующему сеансу Camoufox"""
    ws_url = f"ws://localhost:{port}/{path}"
    
    # Проверяем доступность
    if not await check_camoufox_availability(port):
        raise Exception(f"Порт {port} недоступен")
    
    # Подключаемся
    browser = await self.playwright.firefox.connect(ws_url)
    return browser

Примеры кода для подключения к существующему браузеру

Вот полный рабочий пример, который демонстрирует правильное подключение:

python
import asyncio
from playwright.async_api import async_playwright
from camoufox.server import launch_server
import threading
import time

class CamoufoxSessionManager:
    def __init__(self):
        self.playwright = None
        self.browser = None
        
    async def start_session(self, port=2525, path="browser2525"):
        """Запускаем сессию Camoufox"""
        # Запускаем сервер в отдельном потоке
        server_thread = threading.Thread(
            target=self._run_server,
            args=(port, path, True)
        )
        server_thread.daemon = True
        server_thread.start()
        
        # Ждем запуска сервера
        await asyncio.sleep(3)
        
        # Подключаемся к серверу
        ws_url = f"ws://localhost:{port}/{path}"
        self.playwright = await async_playwright().start()
        self.browser = await self.playwright.firefox.connect(ws_url)
        
        return self.browser
        
    def _run_server(self, port, path, reuse):
        """Запуск сервера Camoufox"""
        from camoufox.server import launch_server
        launch_server(
            headless=True,
            port=port,
            ws_path=path,
            reuse_existing=reuse
        )
        
    async def connect_to_existing(self, port=2525, path="browser2525"):
        """Подключаемся к существующей сессии"""
        if not self.playwright:
            self.playwright = await async_playwright().start()
            
        ws_url = f"ws://localhost:{port}/{path}"
        browser = await self.playwright.firefox.connect(ws_url)
        return browser
        
    async def close_session(self):
        """Закрываем сессию"""
        if self.browser:
            await self.browser.close()
        if self.playwright:
            await self.playwright.stop()

Решение распространенных проблем

Проблема 1: Playwright создает новый браузер вместо подключения к существующему

Причина: Неверный формат WebSocket URL или сервер не настроен на повторное использование.

Решение:

python
# Проверяйте доступность перед подключением
async def check_camoufox_availability(port):
    try:
        import websockets
        async with websockets.connect(f"ws://localhost:{port}") as ws:
            return True
    except:
        return False

# Используйте правильный URL
ws_url = f"ws://localhost:{port}/browser{port}"

Проблема 2: Сессия не сохраняет состояние (cookies, localStorage)

Причина: Camoufox не использует постоянный контекст хранения данных.

Решение:

python
from camoufox import launch

# Запуск с постоянным контекстом
browser = launch(
    headless=False,
    port=2525,
    user_data_dir="./camoufox_profile",  # Папка для хранения данных
    ws_path="browser2525"
)

Проблема 3: WebSocket соединение разрывается

Причина: Отсутствие механизма поддержания соединения.

Решение:

python
# Добавьте пинги для поддержания соединения
async def keep_alive(browser, interval=30):
    """Поддерживаем соединение живым"""
    while True:
        try:
            await browser.contexts[0].evaluate("1")
            await asyncio.sleep(interval)
        except:
            break

Альтернативные подходы к сохранению состояния сессии

Если WebSocket подключение не работает должным образом, рассмотрите следующие альтернативы:

1. Использование userDataDir для сохранения состояния

python
from camoufox import launch

# Запускаем браузер с постоянным хранилищем
browser = launch(
    headless=False,
    user_data_dir="./persistent_profile",
    port=2525,
    ws_path="browser2525"
)

2. Экспорт/импорт cookies

python
# Сохранение cookies
await page.context.storage_state(path="cookies.json")

# Загрузка cookies в новый контекст
context = await browser.new_context(storage_state="cookies.json")

3. Использование Docker для изоляции сессий

python
# Docker-compose.yml для Camoufox
version: '3'
services:
  camoufox:
    image: daijro/camoufox
    ports:
      - "2525:2525"
    volumes:
      - ./profile:/root/.camoufox

Источники

  1. Camoufox Remote Server Documentation - Официальная документация по удаленному серверу Camoufox
  2. GitHub Discussion - Connecting to existing Camoufox instance - Обсуждение подключения к существующим экземплярам Camoufox
  3. Playwright WebSocket API - Документация по WebSocket API Playwright
  4. Persistent Context in Playwright - Руководство по использованию постоянного контекста в Playwright
  5. WebSocket Connection Persistence - Обсуждение поддержания WebSocket соединений

Заключение

Для успешного подключения к существующему сеансу Camoufox выполните следующие ключевые шаги:

  1. Настройте сервер Camoufox с параметром reuse_existing=True для возможности многократных подключений
  2. Используйте правильный формат WebSocket URL: ws://localhost:порт/путь
  3. Реализуйте механизм проверки доступности перед подключением
  4. Рассмотрите альтернативные методы сохранения состояния, такие как user_data_dir или экспорт/импорт cookies
  5. Добавьте обработку ошибок для перехвата разрывов соединения

Основная проблема вашего текущего подхода заключается в том, что сервер Camoufox не настроен на повторное использование существующих экземпляров браузера. После правильной конфигурации вы сможете успешно подключаться к одному и тому же браузерному экземпляру из разных скриптов, сохраняя при этом все сессионные данные (cookies, localStorage и т.д.).

Авторы
Проверено модерацией
Модерация