| |
| |
| |
| |
| |
|
|
| import asyncio |
| import os |
| import platform |
| import subprocess |
| import requests |
| import logging |
|
|
| from playwright.async_api import Browser as PlaywrightBrowser |
| from playwright.async_api import ( |
| BrowserContext as PlaywrightBrowserContext, |
| Playwright, |
| async_playwright, |
| ) |
| from browser_use.browser.browser import Browser |
| from browser_use.browser.context import BrowserContext, BrowserContextConfig |
|
|
| from .config import BrowserPersistenceConfig |
| from .custom_context import CustomBrowserContext |
|
|
| logger = logging.getLogger(__name__) |
|
|
| class CustomBrowser(Browser): |
|
|
| async def new_context( |
| self, |
| config: BrowserContextConfig = BrowserContextConfig() |
| ) -> CustomBrowserContext: |
| return CustomBrowserContext(config=config, browser=self) |
|
|
| async def _setup_browser(self, playwright: Playwright) -> PlaywrightBrowser: |
| """Sets up and returns a Playwright Browser instance.""" |
| try: |
| |
| arc_path = "/Applications/Arc.app/Contents/MacOS/Arc" |
| using_arc = platform.system() == "Darwin" and os.path.exists(arc_path) |
| |
| |
| if using_arc: |
| browser_path = arc_path |
| else: |
| browser_path = self.config.chrome_instance_path |
|
|
| if self.config.wss_url: |
| browser = await playwright.chromium.connect(self.config.wss_url) |
| return browser |
|
|
| |
| try: |
| response = requests.get('http://localhost:9222/json/version', timeout=2) |
| if response.status_code == 200: |
| logger.info('Reusing existing browser instance') |
| browser = await playwright.chromium.connect_over_cdp( |
| endpoint_url='http://localhost:9222', |
| timeout=20000, |
| ) |
| return browser |
| except requests.ConnectionError: |
| logger.debug('No existing browser instance found, starting new one') |
|
|
| if browser_path: |
| |
| if platform.system() == "Darwin": |
| os.system("pkill 'Arc'") |
| await asyncio.sleep(1) |
|
|
| |
| subprocess.Popen( |
| [ |
| browser_path, |
| '--remote-debugging-port=9222', |
| '--no-first-run', |
| '--no-default-browser-check', |
| '--disable-features=Translate', |
| '--enable-automation', |
| '--disable-blink-features=AutomationControlled', |
| ] + self.config.extra_chromium_args, |
| stdout=subprocess.DEVNULL, |
| stderr=subprocess.DEVNULL, |
| ) |
|
|
| |
| for _ in range(10): |
| try: |
| response = requests.get('http://localhost:9222/json/version', timeout=2) |
| if response.status_code == 200: |
| break |
| except requests.ConnectionError: |
| pass |
| await asyncio.sleep(1) |
|
|
| try: |
| browser = await playwright.chromium.connect_over_cdp( |
| endpoint_url='http://localhost:9222', |
| timeout=20000, |
| ) |
| if using_arc: |
| logger.info('Successfully connected to Arc browser') |
| return browser |
| except Exception as e: |
| logger.error(f'Failed to connect to browser: {str(e)}') |
| raise RuntimeError( |
| 'Failed to connect to browser. Please ensure all instances are closed and try again.' |
| ) |
|
|
| |
| disable_security_args = [] |
| if self.config.disable_security: |
| disable_security_args = [ |
| '--disable-web-security', |
| '--disable-site-isolation-trials', |
| '--disable-features=IsolateOrigins,site-per-process', |
| ] |
|
|
| browser = await playwright.chromium.launch( |
| headless=self.config.headless, |
| executable_path=None, |
| args=[ |
| '--no-sandbox', |
| '--disable-blink-features=AutomationControlled', |
| '--disable-infobars', |
| '--disable-background-timer-throttling', |
| '--disable-popup-blocking', |
| '--disable-backgrounding-occluded-windows', |
| '--disable-renderer-backgrounding', |
| '--enable-automation', |
| ] + disable_security_args + self.config.extra_chromium_args, |
| proxy=self.config.proxy, |
| ) |
|
|
| return browser |
|
|
| except Exception as e: |
| logger.error(f'Failed to initialize browser: {str(e)}') |
| raise |
|
|