This repository has been archived on 2025-11-27. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Fitz_Studio/domains/ScrappingWeb/Navegador.py
T
egutierrez aef8791151 feat: Implement main application shell with navigation and color scheme toggle
- Added Appshell component with responsive navbar and main content area
- Integrated ColorSchemeToggle for light/dark mode switching
- Created Welcome component with styled title and introductory text
- Developed ChatPage for LLM interaction with WebSocket support
- Implemented Biblioteca for managing notes with rich text editor
- Added LoginPage for user authentication with error handling
- Introduced MessageList and MessageBubble components for chat messages
- Styled components with CSS modules for consistent design
2025-06-21 02:01:21 +02:00

194 lines
7.2 KiB
Python

import asyncio
import os
import signal
import subprocess
import json
from typing import Optional
import aiohttp
class Navegador:
def __init__(self,
chrome_path: str,
user_data_dir: str,
id: Optional[int] = None,
download_dir: Optional[str] = None,
debugging_port: int = 9222,
headless: bool = False,
user_agent: Optional[str] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"):
self.chrome_path = chrome_path
self.user_data_dir = user_data_dir
self.id = id
self.download_dir = download_dir or os.path.join(self.user_data_dir, "downloads")
self.debugging_port = debugging_port
self.headless = headless
self.user_agent = user_agent
self.chrome_process: Optional[subprocess.Popen] = None
async def _esperar_debugger(self, timeout=10):
url = f"http://127.0.0.1:{self.debugging_port}/json"
for _ in range(timeout * 10): # 10 intentos por segundo
try:
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
if resp.status == 200:
print("✅ Chrome listo para debugging.")
return
except Exception:
pass
await asyncio.sleep(0.1)
raise RuntimeError("❌ Chrome no respondió en el puerto de debugging.")
def _preconfigurar_preferencias(self):
prefs_path = os.path.join(self.user_data_dir, "Default", "Preferences")
os.makedirs(os.path.dirname(prefs_path), exist_ok=True)
os.makedirs(self.download_dir, exist_ok=True)
prefs = {
"profile": {
"exit_type": "Normal",
"exited_cleanly": True
},
"browser": {
"has_seen_welcome_page": True
},
"distribution": {
"skip_first_run_ui": True
},
"download": {
"default_directory": self.download_dir,
"prompt_for_download": False,
"directory_upgrade": True,
"extensions_to_open": ""
},
"savefile": {
"default_directory": self.download_dir
}
}
if os.path.exists(prefs_path):
try:
with open(prefs_path, "r", encoding="utf-8") as f:
existing = json.load(f)
existing.update(prefs)
prefs = existing
except Exception:
pass
with open(prefs_path, "w", encoding="utf-8") as f:
json.dump(prefs, f, indent=2)
def _build_args(self):
os.makedirs(self.user_data_dir, exist_ok=True)
self._preconfigurar_preferencias()
args = [
f"--remote-debugging-port={self.debugging_port}",
f"--user-data-dir={self.user_data_dir}",
"--disable-blink-features=AutomationControlled",
"--no-sandbox",
# "--disable-web-security",
# "--disable-extensions",
# "--disable-dev-shm-usage",
"--disable-infobars",
"--disable-popup-blocking",
"--disable-default-apps",
"--mute-audio",
"--window-size=1024,1024",
"--no-first-run",
"--no-default-browser-check",
"--disable-features=DefaultBrowserPrompt",
"--disable-component-update",
"--disable-background-networking",
"--disable-sync",
"--disable-translate",
"--disable-background-timer-throttling",
"--disable-client-side-phishing-detection",
"--disable-component-extensions-with-background-pages",
"--metrics-recording-only",
"--safebrowsing-disable-auto-update",
]
if self.headless:
args.append("--headless=new")
if self.user_agent:
args.append(f"--user-agent={self.user_agent}")
return args
async def inyectar_spoof_chrome(self):
script = """
window.chrome = {
app: {
isInstalled: false,
InstallState: {
DISABLED: 'disabled',
INSTALLED: 'installed',
NOT_INSTALLED: 'not_installed'
},
RunningState: {
CANNOT_RUN: 'cannot_run',
READY_TO_RUN: 'ready_to_run',
RUNNING: 'running'
}
},
runtime: {
PlatformOs: { MAC: 'mac', WIN: 'win', ANDROID: 'android', CROS: 'cros', LINUX: 'linux', OPENBSD: 'openbsd' },
PlatformArch: { ARM: 'arm', X86_32: 'x86-32', X86_64: 'x86-64' },
PlatformNaclArch: { ARM: 'arm', X86_32: 'x86-32', X86_64: 'x86-64' },
RequestUpdateCheckStatus: { THROTTLED: 'throttled', NO_UPDATE: 'no_update', UPDATE_AVAILABLE: 'update_available' },
OnInstalledReason: { INSTALL: 'install', UPDATE: 'update', CHROME_UPDATE: 'chrome_update', SHARED_MODULE_UPDATE: 'shared_module_update' },
OnRestartRequiredReason: { APP_UPDATE: 'app_update', OS_UPDATE: 'os_update', PERIODIC: 'periodic' }
}
};
"""
url = f"http://127.0.0.1:{self.debugging_port}/json"
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
targets = await resp.json()
for target in targets:
if "webSocketDebuggerUrl" not in target:
continue
target_id = target["id"]
async with session.post(
f"http://127.0.0.1:{self.debugging_port}/json/protocol",
json={"targetId": target_id}
):
pass # CDP protocol fetch optional
async with session.post(
f"http://127.0.0.1:{self.debugging_port}/json/send",
json={
"id": 1,
"method": "Page.addScriptToEvaluateOnNewDocument",
"params": {"source": script}
}
) as inject_resp:
if inject_resp.status == 200:
print("✅ chrome.* spoof inyectado.")
async def iniciar(self):
args = self._build_args()
self.chrome_process = subprocess.Popen([self.chrome_path] + args)
print(f"Chrome iniciado (headless={self.headless}). Esperando disponibilidad del debugger...")
await self._esperar_debugger()
await self.inyectar_spoof_chrome()
async def cerrar(self):
if self.chrome_process and self.chrome_process.poll() is None:
self.chrome_process.terminate()
try:
await asyncio.wait_for(asyncio.to_thread(self.chrome_process.wait), timeout=5)
except asyncio.TimeoutError:
self.chrome_process.kill()
print("🛑 Chrome cerrado correctamente.")