Как подключиться к существующему сеансу Camoufox
Настройка Camoufox для многократных подключений через WebSocket. Сохранение сессий cookies и localStorage между скриптами.
Как подключиться к существующему сеансу браузера Camoufox вместо создания нового?
Я пытаюсь автоматизировать работу с сайтом, используя библиотеку Camoufox. Вот что я делаю:
- Запускаю Camoufox браузер через Python/Playwright на определенном порту:
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 - это порт для последующего подключения.
-
Я вручную вхожу в Google и Midjourney (на основе аккаунта Google), и этот браузер Camoufox должен оставаться работающим долгое время, чтобы другие скрипты могли подключаться к нему.
-
Затем я пытаюсь подключиться к открытому браузеру из другого скрипта:
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 для многократных подключений
- Примеры кода для подключения к существующему браузеру
- Решение распространенных проблем
- Альтернативные подходы к сохранению состояния сессии
Основные методы подключения к существующему сеансу
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 не настроен на повторное использование существующих экземпляров. Вот исправленная конфигурация:
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
Правильная последовательность действий:
- Сначала запустите сервер Camoufox:
# Запускаем сервер один раз
server_thread = threading.Thread(
target=run_server,
args=(2525, "browser2525", True)
)
server_thread.start()
time.sleep(2) # Даем время на запуск сервера
- Затем запустите браузерный экземпляр:
# Запускаем браузерный экземпляр
browser_thread = threading.Thread(
target=launch_camoufox_instance,
args=(2525, "browser2525")
)
browser_thread.start()
time.sleep(5) # Даем время на запуск браузера
- Подключайтесь из других скриптов:
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
Примеры кода для подключения к существующему браузеру
Вот полный рабочий пример, который демонстрирует правильное подключение:
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 или сервер не настроен на повторное использование.
Решение:
# Проверяйте доступность перед подключением
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 не использует постоянный контекст хранения данных.
Решение:
from camoufox import launch
# Запуск с постоянным контекстом
browser = launch(
headless=False,
port=2525,
user_data_dir="./camoufox_profile", # Папка для хранения данных
ws_path="browser2525"
)
Проблема 3: WebSocket соединение разрывается
Причина: Отсутствие механизма поддержания соединения.
Решение:
# Добавьте пинги для поддержания соединения
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 для сохранения состояния
from camoufox import launch
# Запускаем браузер с постоянным хранилищем
browser = launch(
headless=False,
user_data_dir="./persistent_profile",
port=2525,
ws_path="browser2525"
)
2. Экспорт/импорт cookies
# Сохранение cookies
await page.context.storage_state(path="cookies.json")
# Загрузка cookies в новый контекст
context = await browser.new_context(storage_state="cookies.json")
3. Использование Docker для изоляции сессий
# Docker-compose.yml для Camoufox
version: '3'
services:
camoufox:
image: daijro/camoufox
ports:
- "2525:2525"
volumes:
- ./profile:/root/.camoufox
Источники
- Camoufox Remote Server Documentation - Официальная документация по удаленному серверу Camoufox
- GitHub Discussion - Connecting to existing Camoufox instance - Обсуждение подключения к существующим экземплярам Camoufox
- Playwright WebSocket API - Документация по WebSocket API Playwright
- Persistent Context in Playwright - Руководство по использованию постоянного контекста в Playwright
- WebSocket Connection Persistence - Обсуждение поддержания WebSocket соединений
Заключение
Для успешного подключения к существующему сеансу Camoufox выполните следующие ключевые шаги:
- Настройте сервер Camoufox с параметром
reuse_existing=Trueдля возможности многократных подключений - Используйте правильный формат WebSocket URL:
ws://localhost:порт/путь - Реализуйте механизм проверки доступности перед подключением
- Рассмотрите альтернативные методы сохранения состояния, такие как
user_data_dirили экспорт/импорт cookies - Добавьте обработку ошибок для перехвата разрывов соединения
Основная проблема вашего текущего подхода заключается в том, что сервер Camoufox не настроен на повторное использование существующих экземпляров браузера. После правильной конфигурации вы сможете успешно подключаться к одному и тому же браузерному экземпляру из разных скриптов, сохраняя при этом все сессионные данные (cookies, localStorage и т.д.).