Skip to main content
Glama

MCP Selenium WebDriver

by Nixon-Suarez
  • Linux
  • Apple
stealth_features.py16.1 kB
""" Módulo de características avanzadas para evasión de detección. """ import time import random import json from typing import Dict, Any, Optional, List from selenium.webdriver.remote.webdriver import WebDriver from selenium.common.exceptions import WebDriverException from session_manager import SessionManager class StealthFeatures: """Características avanzadas para evasión de detección.""" def __init__(self, session_manager: SessionManager): self.session_manager = session_manager # Scripts para evasión de detección self.stealth_scripts = { "webdriver_property": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined, }); """, "chrome_runtime": """ window.chrome = { runtime: {}, }; """, "permissions": """ const originalQuery = window.navigator.permissions.query; return window.navigator.permissions.query = (parameters) => ( parameters.name === 'notifications' ? Promise.resolve({ state: Notification.permission }) : originalQuery(parameters) ); """, "plugins": """ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5], }); """, "languages": """ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], }); """, "webgl_vendor": """ const getParameter = WebGLRenderingContext.getParameter; WebGLRenderingContext.prototype.getParameter = function(parameter) { if (parameter === 37445) { return 'Intel Inc.'; } if (parameter === 37446) { return 'Intel Iris OpenGL Engine'; } return getParameter(parameter); }; """, "iframe_contentWindow": """ try { if (window.outerHeight === 0) { window.outerHeight = window.innerHeight; } if (window.outerWidth === 0) { window.outerWidth = window.innerWidth; } } catch (e) {} """, "hairline": """ Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { get: function() { if (this.id === 'modernizr') { return 1; } return this.getBoundingClientRect().height; } }); """ } # User agents realistas self.realistic_user_agents = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/121.0", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/120.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/121.0" ] # Resoluciones de pantalla comunes self.common_resolutions = [ (1920, 1080), (1366, 768), (1536, 864), (1440, 900), (1280, 720), (1600, 900), (1024, 768), (1280, 1024) ] def apply_stealth_mode(self, session_id: str) -> Dict[str, Any]: """Aplica todas las técnicas de evasión de detección a una sesión.""" session = self.session_manager.get_session(session_id) if not session: return {"success": False, "error": "Sesión no encontrada"} try: applied_scripts = [] # Aplicar scripts de evasión for script_name, script_code in self.stealth_scripts.items(): try: session.driver.execute_script(script_code) applied_scripts.append(script_name) except Exception as e: # Continuar aunque algunos scripts fallen pass # Configurar propiedades adicionales self._set_navigator_properties(session.driver) return { "success": True, "applied_scripts": applied_scripts, "message": "Modo stealth aplicado exitosamente" } except Exception as e: return { "success": False, "error": str(e), "message": "Error al aplicar modo stealth" } def randomize_user_agent(self, session_id: str) -> Dict[str, Any]: """Cambia el user agent a uno aleatorio.""" session = self.session_manager.get_session(session_id) if not session: return {"success": False, "error": "Sesión no encontrada"} try: new_user_agent = random.choice(self.realistic_user_agents) # Cambiar user agent via JavaScript script = f""" Object.defineProperty(navigator, 'userAgent', {{ get: () => '{new_user_agent}', }}); """ session.driver.execute_script(script) return { "success": True, "new_user_agent": new_user_agent, "message": "User agent randomizado exitosamente" } except Exception as e: return { "success": False, "error": str(e), "message": "Error al randomizar user agent" } def randomize_viewport(self, session_id: str) -> Dict[str, Any]: """Cambia el tamaño de la ventana a una resolución aleatoria.""" session = self.session_manager.get_session(session_id) if not session: return {"success": False, "error": "Sesión no encontrada"} try: width, height = random.choice(self.common_resolutions) # Agregar variación aleatoria width += random.randint(-50, 50) height += random.randint(-30, 30) session.driver.set_window_size(width, height) return { "success": True, "new_size": {"width": width, "height": height}, "message": "Viewport randomizado exitosamente" } except Exception as e: return { "success": False, "error": str(e), "message": "Error al randomizar viewport" } def manage_cookies( self, session_id: str, action: str, cookie_data: Optional[Dict[str, Any]] = None, cookie_name: Optional[str] = None ) -> Dict[str, Any]: """Gestiona cookies de la sesión.""" session = self.session_manager.get_session(session_id) if not session: return {"success": False, "error": "Sesión no encontrada"} try: if action == "get_all": cookies = session.driver.get_cookies() return { "success": True, "cookies": cookies, "count": len(cookies), "message": f"Obtenidas {len(cookies)} cookies" } elif action == "add": if not cookie_data: return {"success": False, "error": "cookie_data requerido para agregar"} session.driver.add_cookie(cookie_data) return { "success": True, "message": f"Cookie '{cookie_data.get('name')}' agregada" } elif action == "delete": if cookie_name: session.driver.delete_cookie(cookie_name) return { "success": True, "message": f"Cookie '{cookie_name}' eliminada" } else: session.driver.delete_all_cookies() return { "success": True, "message": "Todas las cookies eliminadas" } elif action == "get": if not cookie_name: return {"success": False, "error": "cookie_name requerido para obtener"} cookie = session.driver.get_cookie(cookie_name) return { "success": True, "cookie": cookie, "message": f"Cookie '{cookie_name}' obtenida" } else: return { "success": False, "error": f"Acción no válida: {action}. Disponibles: get_all, add, delete, get" } except Exception as e: return { "success": False, "error": str(e), "message": f"Error al gestionar cookies: {action}" } def add_random_delay( self, min_seconds: float = 0.5, max_seconds: float = 2.0 ) -> Dict[str, Any]: """Agrega un delay aleatorio entre acciones.""" try: delay = random.uniform(min_seconds, max_seconds) time.sleep(delay) return { "success": True, "delay_seconds": round(delay, 2), "message": f"Delay de {round(delay, 2)} segundos aplicado" } except Exception as e: return { "success": False, "error": str(e), "message": "Error al aplicar delay" } def simulate_human_typing( self, session_id: str, strategy: str, value: str, text: str, min_delay: float = 0.05, max_delay: float = 0.15, element_index: int = 0 ) -> Dict[str, Any]: """Simula escritura humana con delays aleatorios entre teclas.""" session = self.session_manager.get_session(session_id) if not session: return {"success": False, "error": "Sesión no encontrada"} try: # Importar herramientas de selenium para encontrar elemento from selenium_tools import SeleniumTools selenium_tools = SeleniumTools(self.session_manager) # Encontrar elemento element = selenium_tools._find_element_helper( session.driver, strategy, value, 10, element_index ) # Limpiar campo element.clear() # Escribir caracter por caracter con delays for char in text: element.send_keys(char) delay = random.uniform(min_delay, max_delay) time.sleep(delay) return { "success": True, "text_typed": text, "characters": len(text), "message": "Texto escrito con simulación humana" } except Exception as e: return { "success": False, "error": str(e), "message": "Error al simular escritura humana" } def scroll_like_human( self, session_id: str, direction: str = "down", distance: int = 300, steps: int = 5 ) -> Dict[str, Any]: """Simula scroll humano con movimientos graduales.""" session = self.session_manager.get_session(session_id) if not session: return {"success": False, "error": "Sesión no encontrada"} try: step_distance = distance // steps for i in range(steps): if direction == "down": session.driver.execute_script(f"window.scrollBy(0, {step_distance});") elif direction == "up": session.driver.execute_script(f"window.scrollBy(0, -{step_distance});") else: return {"success": False, "error": "Dirección debe ser 'up' o 'down'"} # Delay aleatorio entre pasos delay = random.uniform(0.1, 0.3) time.sleep(delay) return { "success": True, "direction": direction, "total_distance": distance, "steps": steps, "message": f"Scroll {direction} simulado exitosamente" } except Exception as e: return { "success": False, "error": str(e), "message": "Error al simular scroll" } def _set_navigator_properties(self, driver: WebDriver): """Configura propiedades del navegador para parecer más humano.""" scripts = [ # Configurar timezone """ try { Object.defineProperty(Intl.DateTimeFormat.prototype, 'resolvedOptions', { value: function() { return { timeZone: 'America/New_York', locale: 'en-US' }; } }); } catch (e) {} """, # Configurar memoria del dispositivo """ try { Object.defineProperty(navigator, 'deviceMemory', { get: () => 8, }); } catch (e) {} """, # Configurar número de núcleos de CPU """ try { Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 4, }); } catch (e) {} """, # Configurar plataforma """ try { Object.defineProperty(navigator, 'platform', { get: () => 'Win32', }); } catch (e) {} """ ] for script in scripts: try: driver.execute_script(script) except: pass # Continuar aunque algunos scripts fallen

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Nixon-Suarez/MCP-Selenium-WebDriver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server