Spaces:
Running
Running
| import asyncio | |
| import os | |
| from playwright.async_api import async_playwright | |
| try: | |
| from tools.find_browsers import find_registry_browsers, find_common_path_browsers, find_playwright_browsers, deduplicate_browsers | |
| except ImportError: | |
| # Handle running from root or tools dir | |
| import sys | |
| sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| from tools.find_browsers import find_registry_browsers, find_common_path_browsers, find_playwright_browsers, deduplicate_browsers | |
| def get_browsers(): | |
| r_browsers = find_registry_browsers() | |
| p_browsers = find_common_path_browsers() | |
| pw_browsers = find_playwright_browsers() | |
| return deduplicate_browsers(r_browsers + p_browsers + pw_browsers) | |
| async def launch_browser(browser_info, use_stealth=True, url="https://bot.sannysoft.com"): | |
| """ | |
| Launches the specified browser with Playwright. | |
| Args: | |
| browser_info (dict): The browser dictionary from find_browsers. | |
| use_stealth (bool): Whether to apply stealth args (Chromium only, excludes Brave). | |
| url (str): Initial URL to open. | |
| """ | |
| name = browser_info.get("name", "Unknown") | |
| path = browser_info.get("path") | |
| engine_type = browser_info.get("type", "unknown") | |
| print(f"\nLaunching {name}...") | |
| print(f"Path: {path}") | |
| print(f"Engine: {engine_type}") | |
| # Logic: Optional stealth mode only for Chromium, excluding Brave | |
| is_chromium = engine_type == "chromium" | |
| is_brave = "brave" in name.lower() | |
| # args to pass to launch_persistent_context or launch | |
| launch_args = [] | |
| ignore_default_args = [] | |
| if use_stealth: | |
| if is_chromium and not is_brave: | |
| print(">> STATUS: Applying Stealth Mode (Chromium detected, not Brave)") | |
| # Common stealth args for Chromium | |
| launch_args.extend([ | |
| "--disable-blink-features=AutomationControlled", | |
| "--no-sandbox", | |
| "--disable-infobars", | |
| "--disable-dev-shm-usage", | |
| "--disable-gpu", # Sometimes helps, sometimes hurts, usually safe for stealth | |
| ]) | |
| # Simple webdriver removal via arg is tricky, best done via add_init_script below | |
| elif is_brave: | |
| print(">> STATUS: Stealth Mode SKIPPED (Brave detected - using built-in shields)") | |
| else: | |
| print(f">> STATUS: Stealth Mode SKIPPED ({engine_type} engine)") | |
| else: | |
| print(">> STATUS: Stealth Mode DISABLED by user request") | |
| async with async_playwright() as p: | |
| browser_type_obj = None | |
| if engine_type == "chromium": | |
| browser_type_obj = p.chromium | |
| elif engine_type == "firefox": | |
| browser_type_obj = p.firefox | |
| else: | |
| # Fallback based on name guessing or default to chromium | |
| if "firefox" in name.lower(): | |
| browser_type_obj = p.firefox | |
| else: | |
| browser_type_obj = p.chromium | |
| try: | |
| # We use launch_persistent_context to simulate a real user session better if needed, | |
| # but for a simple launcher 'launch' is safer to avoid profile locking issues unless requested. | |
| # Using standard launch with executable_path | |
| browser = await browser_type_obj.launch( | |
| executable_path=path, | |
| headless=False, # We want to see the browser | |
| args=launch_args, | |
| ignore_default_args=ignore_default_args if ignore_default_args else None | |
| ) | |
| context = await browser.new_context( | |
| viewport={"width": 1280, "height": 720}, | |
| # user_agent=... # Could customize if needed | |
| ) | |
| # Additional Stealth via JS Injection | |
| if use_stealth and is_chromium and not is_brave: | |
| await context.add_init_script(""" | |
| Object.defineProperty(navigator, 'webdriver', { | |
| get: () => undefined | |
| }); | |
| """) | |
| page = await context.new_page() | |
| await page.goto(url) | |
| print(f"Opened {url}. Press Ctrl+C in terminal to exit (or close browser window).") | |
| # Keep alive loop | |
| try: | |
| while True: | |
| await asyncio.sleep(1) | |
| if page.is_closed(): | |
| break | |
| except KeyboardInterrupt: | |
| print("Closing...") | |
| await browser.close() | |
| except Exception as e: | |
| print(f"Error launching browser: {e}") | |
| def main(): | |
| browsers = get_browsers() | |
| if not browsers: | |
| print("No browsers found!") | |
| return | |
| print("Available Browsers:") | |
| for idx, b in enumerate(browsers): | |
| print(f"{idx + 1}. [{b['source']}] {b['name']}") | |
| choice = input("\nSelect browser number to launch: ") | |
| try: | |
| idx = int(choice) - 1 | |
| if 0 <= idx < len(browsers): | |
| selected_browser = browsers[idx] | |
| stealth_input = input("Enable Stealth Mode? (Y/n): ").lower() | |
| use_stealth = stealth_input != 'n' | |
| target_url = input("Enter URL (default: bot.sannysoft.com): ") | |
| if not target_url: | |
| target_url = "https://bot.sannysoft.com" | |
| elif not target_url.startswith("http://") and not target_url.startswith("https://"): | |
| target_url = "https://" + target_url | |
| asyncio.run(launch_browser(selected_browser, use_stealth, target_url)) | |
| else: | |
| print("Invalid selection.") | |
| except ValueError: | |
| print("Invalid input.") | |
| if __name__ == "__main__": | |
| main() | |