diff --git a/metricas_gugler.py b/metricas_gugler.py new file mode 100644 index 0000000..46bddf7 --- /dev/null +++ b/metricas_gugler.py @@ -0,0 +1,191 @@ +from selenium import webdriver +from selenium.webdriver.chrome.options import Options +from selenium.webdriver.support.ui import WebDriverWait +from selenium.common.exceptions import TimeoutException, WebDriverException +from dotenv import load_dotenv +from email.message import EmailMessage +from urllib.parse import urlparse +import time +import os +import smtplib +import requests + +# Umbrales por red (en segundos) +UMBRAL_POR_RED = { + "3G": 4, + "4G": 3, + "WiFi": 2, + "sin_limitaciones": 2 +} + +# Perfiles de red con latencia, descarga, subida y tipo conexión +PERFILES_RED = { + "3G": {"latency": 150, "download": 3, "upload": 3, "type": "cellular3g"}, + "4G": {"latency": 50, "download": 40, "upload": 40, "type": "cellular4g"}, + "WiFi": {"latency": 20, "download": 150, "upload": 150, "type": "wifi"}, + "sin_limitaciones": {"latency": 0, "download": 0, "upload": 0, "type": "sin_limitaciones"} +} + +URL_TEST = "https://www.gugler.com.ar" +logs = [] +resumen_tabla = [] + +def enviar_email(contenido, asunto="Reporte de performance web - Selenium", destinatario="exequiel84@gmail.com"): + load_dotenv() + remitente = os.getenv("EMAIL") + password = os.getenv("PASSWORD") + + if not remitente or not password: + log("❌ ERROR: EMAIL o PASSWORD no definidos en el archivo .env") + return + + if not destinatario: + destinatario = remitente + + msg = EmailMessage() + msg['Subject'] = asunto + msg['From'] = remitente + msg['To'] = destinatario + msg.set_content(contenido) + + try: + log("\n📤 Enviando correo ...") + with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp: + smtp.login(remitente, password) + smtp.send_message(msg) + log("✅ Correo enviado exitosamente.") + except Exception as e: + log(f"❌ Error al enviar el correo: {e}") + +def log(msg): + print(msg) + logs.append(msg) + +def limpiar_cache(driver): + driver.execute_cdp_cmd('Network.clearBrowserCache', {}) + driver.execute_cdp_cmd('Network.clearBrowserCookies', {}) + log("🧹 Caché y cookies limpiadas.") + time.sleep(4) + +def emular_red(driver, latencia_ms, descarga_mbps, subida_mbps, tipo_conexion): + if tipo_conexion == "sin_limitaciones": + driver.execute_cdp_cmd("Network.disable", {}) + return + driver.execute_cdp_cmd("Network.enable", {}) + driver.execute_cdp_cmd("Network.emulateNetworkConditions", { + "offline": False, + "latency": latencia_ms, + "downloadThroughput": descarga_mbps * 1_000_000, + "uploadThroughput": subida_mbps * 1_000_000, + "connectionType": tipo_conexion, + }) + +def medir_carga(driver, umbral_total, nombre_red): + try: + driver.execute_cdp_cmd("Network.setExtraHTTPHeaders", {"headers": {"Cache-Control": "no-store"}}) + driver.get(URL_TEST) + WebDriverWait(driver, 60).until(lambda d: d.execute_script("return document.readyState") == "complete") + WebDriverWait(driver, 10).until(lambda d: d.execute_script( + "return window.performance.getEntriesByType('resource').filter(e => e.responseEnd == 0).length == 0")) + + timing = driver.execute_script("return window.performance.timing") + tiempo_total = (timing.get('loadEventEnd', 0) - timing.get('navigationStart', 0)) / 1000 + + log(f"\n⏱ Tiempo de carga total: {tiempo_total:.2f} s") + log("✅ Dentro del umbral total" if tiempo_total <= umbral_total else f"⚠️ Superó el umbral total de {umbral_total}s") + + recursos = driver.execute_script("return window.performance.getEntriesByType('resource')") + recursos_rotos = 0 + url_base = urlparse(URL_TEST).netloc + recursos_filtrados = [] + + for r in recursos: + url_recurso = r.get('name', '') + host_recurso = urlparse(url_recurso).netloc + recurso_url = urlparse(url_recurso).path if host_recurso == url_base else url_recurso + recursos_filtrados.append({ + "duracion": r.get('duration', 0), + "url": recurso_url, + "tipo": r.get('initiatorType', 'desconocido') + }) + + log(f"\n📦 {len(recursos)} Recursos individuales (ordenados por duración):") + for r in sorted(recursos_filtrados, key=lambda x: x['duracion'], reverse=True): + dur_segundos = r['duracion'] / 1000 + url_recurso = r['url'] + if url_recurso.startswith("/"): + url_completa = URL_TEST.rstrip("/") + url_recurso + elif url_recurso.startswith("http"): + url_completa = url_recurso + else: + continue + + try: + resp = requests.head(url_completa, timeout=5, allow_redirects=True) + status = resp.status_code + ok = status in [200, 304] + except Exception: + status = "ERR" + ok = False + + if not ok: + recursos_rotos += 1 + + icono = "✅" if ok and dur_segundos <= 1 else "⚠️" + estado_http = f"HTTP {status}" + log(f" {icono} {dur_segundos:.2f}s [{r['tipo']}] - {url_recurso} → {estado_http}") + + resumen_tabla.append({ + "red": nombre_red, + "tiempo_total": tiempo_total, + "umbral": umbral_total, + "recursos": len(recursos), + "rotos": recursos_rotos, + "supero_umbral": tiempo_total > umbral_total + }) + + except TimeoutException: + log("⏰ Timeout esperando que el DOM termine de cargar.") + except WebDriverException as e: + log(f"❌ Error durante la prueba: {e}") + +def mostrar_tabla_resumen(): + log("\n📊 Tabla resumen final:") + header = f"{'Red':<25} {'Tiempo (s)':<12} {'Umbral (s)':<12} {'Recursos':<10} {'Rotos':<8} {'Estado'}" + log(header) + log("-" * len(header)) + for fila in resumen_tabla: + estado = "⚠️ Lento" if fila["supero_umbral"] else "✅ Ok" + log(f"{fila['red']:<25} {fila['tiempo_total']:<12.2f} {fila['umbral']:<12} {fila['recursos']:<10} {fila['rotos']:<8} {estado}") + +def main(): + options = Options() + # options.add_argument("--headless") + options.add_argument("--incognito") + options.add_argument("--disable-gpu") + options.add_argument("--enable-logging") + + driver = webdriver.Remote( + command_executor='http://localhost:4444/wd/hub', + options=options + ) + driver.set_page_load_timeout(60) + try: + for nombre_red, params in PERFILES_RED.items(): + if nombre_red in UMBRAL_POR_RED: + log(f"\n=== 🌐 Probando conexión: {nombre_red} ===") + try: + driver.get("https://www.google.com") + limpiar_cache(driver) + emular_red(driver, params['latency'], params['download'], params['upload'], params['type']) + medir_carga(driver, UMBRAL_POR_RED[nombre_red], nombre_red) + except Exception as e: + log(f"❌ Error durante la prueba con {nombre_red}: {str(e)}") + mostrar_tabla_resumen() + finally: + driver.quit() + +if __name__ == "__main__": + main() + contenido_email = "\n".join(logs) + enviar_email(contenido_email) diff --git a/test_buscador.php b/test_buscador.php new file mode 100644 index 0000000..0d7fe98 --- /dev/null +++ b/test_buscador.php @@ -0,0 +1,172 @@ +load(); +$email = $_ENV['EMAIL']; +$password = $_ENV['PASSWORD']; + +// Crear ChromeOptions + +$options = new ChromeOptions(); +$options->addArguments([ + '--start-maximized', + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36', + '--disable-blink-features=AutomationControlled' +]); +$host = 'http://localhost:4444/wd/hub'; +$capabilities = DesiredCapabilities::chrome(); +$capabilities->setCapability(ChromeOptions::CAPABILITY, $options); +$capabilities->setCapability('pageLoadStrategy', 'normal'); + +//DEFINIMOS LOS SITIOS OFICIALES + +$sitios_oficiales = [ + 'https://www.gugler.com.ar/', + 'https://mi.gugler.com.ar/', + 'https://campusvirtual.gugler.com.ar/' + ]; + +//COMENZAMOS EL TEST + + try { + $palabra_buscar = "gugler"; + $logs =""; + // Crear el cliente de Selenium + echo "0 - Ejecutando test de monitoreo del sitio oficial en Chrome.\n"; + //$driver = RemoteWebDriver::create($host, $capabilities); // opcion para las capabilities. + $driver = RemoteWebDriver::create($host, [ + 'browserName' => 'chrome', + 'goog:chromeOptions' => $options->toArray(), + 'pageLoadStrategy' => 'normal' + ]); + $wait = new WebDriverWait($driver, 10); + $driver->executeScript("Object.defineProperty(navigator, 'languages', {get: () => ['es-ES', 'es']})"); + $driver->executeScript("Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3]})"); + $driver->manage()->window()->maximize(); + + // Paso 1: Navegar a Google + $driver->get('https://www.google.com/'); + echo "1 - Ingresando al buscador google.\n"; + $driver->executeScript("window.scrollTo(0, 500)"); + $searchBox = $driver->findElement(WebDriverBy::name('q')); + + // Paso 2: Ingresar la palabra "gugler" en el cuadro de búsqueda + $letras = str_split($palabra_buscar); + foreach ($letras as $letra) { + $searchBox->sendKeys($letra); + sleep(rand(1, 2)); # Simula escritura + } + $searchBox->submit(); + echo "2 - Se realizó la búsqueda de la palabra --> ". $palabra_buscar .".\n"; + + // Paso 3: Esperar a que se carguen los resultados + sleep(2); // Esperar a que se carguen los resultados + $captcha = $driver->findElements(WebDriverBy::id('captcha-form')); + if ($captcha) { + echo "⚠️ Captcha detectado, se espera 15 segundos para completarlo.\n"; + sleep(15); + } + + // Verificar si el primer resultado es uno de los sitios oficiales + $wait->until( + WebDriverExpectedCondition::presenceOfElementLocated( + WebDriverBy::cssSelector('div#search a[href^="http"]') + ) + ); + // Obtener el primer resultado + $resultados = $driver->findElements(WebDriverBy::cssSelector('div#center_col a[href^="http"]')); + $primero = $resultados[0]->getAttribute('href'); + + + // Se muestran todos los resultados + echo "\n"; + $lista_resultados = ""; + foreach ($resultados as $index => $elemento) { + $url = $elemento->getAttribute('href'); + // Valor por defecto + $esPatrocinado = ""; + // Buscar si el enlace está dentro de un bloque de anuncios (#tads o #tadsb) + $anuncios = $elemento->findElements( + WebDriverBy::xpath('ancestor::*[@id="tads" or @id="tadsb"]') + ); + if (count($anuncios) > 0) { + $esPatrocinado = "(Patrocinado)"; + } + $lista_resultados .= "Resultado #" . sprintf("%2d",($index + 1)) . " " . $esPatrocinado . ": " . substr($url,0,50) . "\n"; + echo " Resultado #" . sprintf("%2d",($index + 1)) . " " . $esPatrocinado . ": " . substr($url,0,50) . "\n"; + } + echo "\n"; + + // Comprobamos si el primer resultado está en nuestra lista de sitios oficiales + echo "3 - Comprobando el resultado con la lista de sitios oficiales.\n"; + echo "4 - Resultado del test: "; + if (in_array($primero, $sitios_oficiales)) { + $detectado = false; + $logs .= "✅ ¡Test exitoso! El primer resultado es un sitio oficial --> ". $primero .".\n"; + } else { + $detectado = true; + $logs .= "❌ Test fallido. El primer resultado no es un sitio oficial --> ". $primero .".\n"; + } + echo $logs; + echo "5 - Se realizó una captura de pantalla.\n"; + $screenshotPath = './capturas/google_search.png'; // Asegúrate de que este directorio sea escribible + $driver->takeScreenshot($screenshotPath); + + // Se realiza una captura de pantalla + echo "6 - Se envia correo electrónico con la captura de pantalla del sitio detectado.\n"; + if ($detectado) { + + $mail = new PHPMailer(true); + try { + // Configuración del servidor SMTP + $mail->isSMTP(); + $mail->Host = 'smtp.gmail.com'; + $mail->SMTPAuth = true; + $mail->Username = $email; // Tu correo de Gmail + $mail->Password = $password; // Tu contraseña + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = 587; + $mail->isHTML(true); + // Remitente y destinatario + $mail->setFrom('ccharlaselenium@gmail.com', 'Monitoreo Buscador - Posible phishing de sitio Gugler'); + $mail->addAddress('exequiel84@gmail.com'); // Destinatario + + // Asunto y cuerpo del correo + $mail->Subject = 'Monitoreo Buscador - Posible phishing de sitio Gugler'; + $cuerpo_mail = 'Se ha detectado un posible intento de phishing del sitio oficial que se esta comprobando. Se incluye una captura de pantalla con los resultados de la prueba y el listado completo de resultados.

Resultado del test:

'; + $cuerpo_mail .= $logs; + $cuerpo_mail .= "

Lista de resultados:

"; + $cuerpo_mail .= nl2br($lista_resultados); + $cuerpo_mail .= "
Quedamos a disposición ante cualquier consulta.
Saludos cordiales.
Sector de Monitoreo."; + $mail->Body = $cuerpo_mail; + // Adjuntar la captura de pantalla + $mail->addAttachment($screenshotPath); + // Enviar el correo + $mail->send(); + echo '7 - Se envió correo con el caso detectado.\n'; + } catch (Exception $e) { + echo "7 - Hubo un error al enviar el correo: {$mail->ErrorInfo}"; + } + } else { echo "7 - No se envió correo ya que no se detectó un sitio no oficial.\n";} + + } catch (Exception $e) { + echo "Importante, hubo un error el test: " . $e->getMessage() . "\n"; + } finally { + // Cerrar el driver + $driver->quit(); + } +?> +