Saltar al contenido
Inicio 100 Días de Código en Python — Día 50: Bots en aplicaciones sociales (el caso de Tinder)

100 Días de Código en Python — Día 50: Bots en aplicaciones sociales (el caso de Tinder)

Nivel: Grado décimo Área: Tecnología e Informática Modalidad: Tutorial práctico Fuente: Curso "100 Days of Code: The Complete Python Pro Bootcamp" (Angela Yu, App Brewery). Contenido del Día 50 (nivel intermedio+).

Este tutorial adapta pedagógicamente el Día 50. Las secciones 📝 Contenido original del curso provienen de los archivos del curso (lecciones 368 a 373). Las soluciones oficiales (para Tinder y para el clon TinDog) están en los gists enlazados en cada paso. Los retos 🟢🟡🟠🔴, la práctica local de la sección 2, el proyecto extra y el proyecto integrador son creaciones de esta adaptación. Las correcciones al material original aparecen como 🛠️ Nota técnica.

Nota sobre las verificaciones: el 26 de septiembre de 2026, con Python 3.14, Selenium 4.49 y Chrome 153 (headless), se comprobó el manejo de ventanas nuevas (window_handles, switch_to.window) con páginas locales creadas para esta guía. No se crearon cuentas en Tinder, Facebook ni TinDog.

🔞 Adaptación obligatoria para el aula:

  1. Tinder exige ser mayor de edad (18 años). Los estudiantes de grado décimo no deben crear cuentas en aplicaciones de citas, ni propias ni "de prueba".
  2. El curso sugiere crear cuentas de Facebook nuevas con fotos generadas por IA (thispersondoesnotexist.com). Eso significa crear perfiles falsos, lo cual va contra las normas de Facebook y de Tinder y engaña a personas reales que creerán estar hablando con alguien que existe. No se hará en clase.
  3. El curso ofrece un clon de práctica, TinDog (perfiles de perros), que requiere registrarse en app.100daysofpython.dev. Si se usa, que sea con una cuenta creada y administrada por el docente.
  4. Esta guía propone, además, una práctica local (sección 2) que enseña exactamente las mismas técnicas de Selenium sin cuentas ni datos de otras personas.

Tabla de contenidos

  1. Antes de empezar: el problema que plantea el curso
  2. Los pasos del curso
  3. Práctica local: ventanas emergentes, avisos y clics con pausas
  4. Ética de los bots en plataformas sociales
  5. 🚀 Proyecto del día: el bot de TinDog o la votación de la mascota
  6. 🌟 Proyecto extra: el detector de bots
  7. 🏆 Proyecto integrador del bloque (Días 45 a 51) — Etapa 6
  8. 🧩 Comprueba lo aprendido
  9. 🤖 Programar con apoyo de IA
  10. 🛠️ Correcciones técnicas al material original
  11. 📋 Matriz de trazabilidad
  12. 📦 Evidencias de aprendizaje del Día 50

0. Antes de empezar: el problema que plantea el curso

(Fuente: 368 - Day 50 Goals- what you will make by the end of the day.md)

Es la mitad del curso, y la profesora propone un proyecto "para celebrar": un bot que da "me gusta" automáticamente en Tinder, una aplicación de citas en línea donde ves perfiles y marcas "me gusta" o "no me gusta"; si dos personas se gustan mutuamente, hay una coincidencia (match) y pueden conversar.

La historia: en una reunión, varios amigos de la profesora se quejaban de pasar horas en la aplicación con muy pocas coincidencias. Ella buscó datos:

  • Un usuario de Reddit publicó sus estadísticas: 110 coincidencias en 26 800 "deslizamientos" en cuatro años (0,41 %).
  • Otro: 133 coincidencias en 12 631 (cerca de una por cada cien).
  • Según una entrevista del New York Times a la empresa en 2014, los usuarios entraban unas 11 veces al día, con sesiones de unos 7 a 8,5 minutos: alrededor de 90 minutos diarios.

La idea: automatizar el proceso para ahorrar tiempo. Existen incluso aparatos físicos ("Tinder finger") que deslizan el dedo en el teléfono sin parar.

📖 Lectura crítica (adaptación)

Antes de programar, analicemos el planteamiento con los datos del propio curso:

  • Cálculo: 110 / 26 800 = 0,0041 → 0,41 %. El dato es correcto, pero ¿qué dice? Quien da "me gusta" a todo el mundo sin mirar recibe muy pocas coincidencias. Un bot que hace lo mismo, más rápido, no resuelve ese problema: lo multiplica.
  • Consentimiento y respeto: del otro lado hay personas reales que reciben un "me gusta" que nadie dio de verdad. La propia profesora lo reconoce: sugiere presionar "No" a todos "para no romper corazones" y advierte que puede traer problemas con la pareja.
  • Reglas de la plataforma: las aplicaciones sociales prohíben los bots y bloquean las cuentas que los usan (el curso advierte que Facebook podría desactivar tu cuenta).

Por eso, en esta guía el valor del día está en las técnicas de Selenium (ventanas emergentes, avisos, esperas, excepciones), que se practicarán en entornos seguros, y en una reflexión ética sobre los bots en plataformas sociales.

Prerequisitos: Selenium (Días 48 y 49), excepciones (Día 30).


1. Los pasos del curso

(Fuentes: 369 a 373)

📝 Contenido original del curso

Paso 1 — Cuenta (369)

  • Opción A: registrarse en TinDog, el clon de práctica (app.100daysofpython.dev).
  • Opción B: usar Tinder real con inicio de sesión con Facebook o Google (o pedir ayuda a un amigo, o crear una cuenta nueva con una foto generada por IA). (Ver el aviso inicial: no se hace en clase.)
  • Recorrer a mano el proceso para identificar los elementos que el código deberá encontrar.
  • Nota de la profesora: si no quieres ilusionar a nadie, presiona "NOPE" con todos.

Paso 2 — Ir a la página de inicio de sesión (370)

  • Se usa el inicio de sesión con Facebook para evitar la verificación por teléfono cada vez (el de Google tiene más pasos). La verificación del teléfono hay que hacerla a mano una vez, porque no se puede automatizar.
  • Con Selenium: abrir la página, clic en LOG IN y luego en LOGIN WITH FACEBOOK; debe aparecer la ventana emergente de Facebook.
  • Pistas: si aparece NoSuchElementException, agrega una pausa entre clics para que cargue el siguiente elemento; copiar el XPath con clic derecho facilita encontrar los botones.

Paso 3 — Iniciar sesión con Facebook (371)

  • La página de Facebook se abre en otra ventana, y Selenium sigue "mirando" la primera. Cada ventana tiene un identificador (handle):
Python
  base_window = driver.window_handles[0]        # la ventana original
  fb_login_window = driver.window_handles[1]    # la ventana emergente
  driver.switch_to.window(fb_login_window)
  print(driver.title)                           # debe decir "Facebook"
  • Llenar y enviar el formulario de Facebook; luego volver a la ventana original y comprobar su título ("Tinder | Match. Chat. Date.").
  • Advertencia del curso: no inicies sesión demasiadas veces seguidas, porque Facebook puede tomarte por un bot y desactivar la cuenta.

Paso 4 — Cerrar los avisos (372)

  • Al entrar aparecen ventanas modales: ubicación (clic en ALLOW), notificaciones (NOT INTERESTED) y cookies (I ACCEPT). Pistas: usar XPath y pausas.

Paso 5 — "Me gusta" (373)

  • En la versión web basta con hacer clic en el botón "Like", con al menos 1 segundo entre clics para no parecer un bot.
  • Pista 1: la aplicación tarda en cargar perfiles; mientras tanto el botón no existe (NoSuchElementException). Manejar la excepción y esperar 2 segundos antes de reintentar.
  • Pista 2: cuando hay una coincidencia, aparece una ventana encima del botón y el clic falla con ElementClickInterceptedException. Hay que cerrarla ("BACK TO TINDER") para seguir.
  • Límites: la versión gratuita de Tinder permite 100 "me gusta" al día; TinDog, solo 20.

🔍 Conceptos técnicos que deja el día

Concepto Para qué sirve
driver.window_handles Lista de las ventanas y pestañas abiertas
driver.switch_to.window(handle) Cambiar la ventana que controla Selenium
driver.title Comprobar en qué ventana estás
NoSuchElementException El elemento aún no existe (carga lenta)
ElementClickInterceptedException Otro elemento tapa el que quieres clicar
Pausas entre acciones No saturar el servidor ni disparar sus defensas contra bots

🛠️ Nota técnica: el curso usa pausas fijas (sleep) y reintentos manuales. Con lo aprendido en el Día 49, es mejor WebDriverWait con EC.number_of_windows_to_be(2) para esperar la ventana emergente, y EC.element_to_be_clickable(...) para esperar el botón. Para las pausas entre "me gusta", en cambio, sí tiene sentido un sleep: no se está esperando a que algo cargue, sino limitando el ritmo del bot.


2. Práctica local: ventanas emergentes, avisos y clics con pausas

(Adaptación pedagógica; no existe en el curso original.)

🎯 Objetivo de aprendizaje

Practicar las técnicas de los pasos 2 a 5 (cambiar de ventana, cerrar avisos, manejar excepciones y controlar el ritmo) con páginas propias.

📖 Preparación: páginas de práctica

Crea una carpeta votacion/ con estas páginas (HTML de los Días 41 y 42):

  • index.html: un h1 y dos enlaces:
    • <a id="entrar" href="login.html" target="_blank">Entrar con el carné</a> → target="_blank" abre otra ventana, como la de Facebook en el curso.
    • <a id="empezar" href="opcion1.html">Empezar</a>
  • login.html: un formulario sencillo con un campo codigo.
  • opcion1.html, opcion2.html, …: cada una con un nombre posible para la mascota del colegio y dos enlaces, <a id="si" href="opcion2.html?voto=si">Me gusta</a> y <a id="no" href="opcion2.html?voto=no">No</a>.
  • En alguna opción, agrega un "aviso" que tape el contenido (por ejemplo, un div con CSS position: fixed que cubra la pantalla y un enlace "Cerrar" que lleve a la misma página sin el aviso). Así podrás provocar un ElementClickInterceptedException.

🔎 Ejemplo explicado (verificado con páginas locales)

Python
import pathlib
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get(pathlib.Path("votacion/index.html").resolve().as_uri())   # abre un archivo local

base_window = driver.window_handles[0]
driver.find_element(By.ID, "entrar").click()       # se abre una ventana nueva
print(len(driver.window_handles))                  # 2
driver.switch_to.window(driver.window_handles[1])
print(driver.title)                                # Carné estudiantil
driver.switch_to.window(base_window)               # volver a la ventana original
print(driver.title)                                # Votación

pathlib.Path(...).resolve().as_uri() convierte la ruta de un archivo en una dirección file:///... que el navegador entiende.

📝 Actividad

  1. Automatiza: abrir index.html, abrir la ventana del carné, escribir un código ficticio, volver a la ventana original.
  2. Recorre las opciones votando según una lista predefinida (por ejemplo, ["si", "no", "si"]), con 1 segundo entre votos.
  3. Si un aviso tapa el botón, atrapa ElementClickInterceptedException, ciérralo y vuelve a intentar.
  4. Limita el bot a un máximo de N votos (como el límite diario de la aplicación).
  5. Imprime un resumen: votos "sí", votos "no", avisos cerrados.

🔍 Antes de programar

  • ¿Cómo sabe tu programa en qué ventana está en cada momento?
  • ¿Qué excepción esperas en cada situación y qué debe hacer el bot en cada caso?
  • ¿Dónde tiene sentido una espera (WebDriverWait) y dónde una pausa fija?

⚠️ Errores frecuentes

Error Causa Solución
IndexError en window_handles[1] La ventana aún no se abrió WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
Selenium no encuentra elementos después de abrir la ventana Sigue controlando la ventana original switch_to.window(...)
NoSuchWindowException Se cerró la ventana que Selenium estaba controlando Vuelve a base_window
ElementClickInterceptedException Un aviso tapa el botón Ciérralo primero
Ciclo infinito de reintentos No hay límite Máximo de intentos (función retry del Día 49)

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: cuenta las ventanas abiertas después de cada clic e imprímelas con su título.
  • 🟡 Reto 2: abre tres ventanas y cierra solo la del medio con driver.close() (recuerda cambiar antes a esa ventana). Luego vuelve a la original.
  • 🟠 Reto 3: haz que el aviso aparezca al azar (genera las páginas con un programa de Python que decida en cuáles poner el aviso). Tu bot debe funcionar sin saber de antemano dónde aparecerá.
  • 🔴 Reto 4 — Pensamiento computacional: diseña el diagrama de estados del bot (esperando perfil → votando → aviso abierto → límite alcanzado → fin) y úsalo para escribir el ciclo principal.

3. Ética de los bots en plataformas sociales

(Adaptación pedagógica basada en las advertencias del propio curso.)

Preguntas para el debate

  1. ¿Qué diferencia hay entre un bot que juega por ti en un juego de un solo jugador (Día 48) y uno que interactúa con personas en una red social?
  2. El curso advierte que Facebook puede desactivar tu cuenta si parece un bot. ¿Por qué las plataformas se defienden de los bots? ¿A quién protegen?
  3. Crear un perfil con la foto de una persona que no existe (generada por IA): ¿es un juego inofensivo o un engaño? ¿Qué pasa con la confianza de quienes usan la plataforma?
  4. En redes sociales, los bots se usan también para inflar seguidores, difundir noticias falsas o acosar. ¿Qué responsabilidad tiene quien programa un bot?
  5. ¿En qué casos un bot en una plataforma social sí aporta valor? (Por ejemplo: bots que se identifican como bots y responden preguntas frecuentes, o que publican alertas meteorológicas.)

Criterios para un bot responsable (propuesta de esta guía)

Criterio Pregunta
Transparencia ¿Las personas saben que están interactuando con un programa?
Consentimiento ¿Las personas afectadas aceptaron esa interacción?
Reglas ¿Los términos de la plataforma lo permiten? ¿Hay una API oficial?
Ritmo ¿El bot actúa a una velocidad razonable, sin saturar el servicio?
Datos ¿Recolecta datos personales? ¿Con autorización (Ley 1581 de 2012)?
Edad ¿Quien lo usa cumple la edad mínima del servicio?

Actividad

Evalúa con la tabla anterior tres bots: el de Tinder del curso, el de Cookie Clicker (Día 48) y un bot de preguntas frecuentes de la página de tu colegio (real o imaginado). Concluye con un párrafo.


4. 🚀 Proyecto del día: el bot de TinDog o la votación de la mascota

(Integra las técnicas de los pasos 2 a 5 del curso: 370 a 373.)

Problema

Automatizar una secuencia completa en una aplicación web: entrar, cerrar avisos y realizar una acción repetida con límites y manejo de errores.

Contexto

Dos opciones, ambas seguras:

  • Opción A (docente o en casa con supervisión): el bot de TinDog, el clon de práctica del curso, con la cuenta del docente.
  • Opción B (en clase): el bot de la votación de la mascota del colegio con las páginas locales de la sección 2.

Objetivo

Un bot que complete el recorrido sin intervención y termine con un resumen.

Requisitos funcionales

  1. Abrir la página e iniciar sesión en la ventana emergente, volviendo a la ventana original.
  2. Cerrar los avisos que aparezcan (ubicación, notificaciones y cookies en TinDog; tu aviso en la opción B).
  3. Realizar la acción ("Like"/"Nope" en TinDog; voto en la opción B) con al menos 1 segundo entre acciones.
  4. Manejar NoSuchElementException (esperar y reintentar) y ElementClickInterceptedException (cerrar lo que tapa y reintentar).
  5. Respetar el límite (20 en TinDog, N en la opción B).
  6. Imprimir un resumen.

Restricciones técnicas

  • Credenciales en .env (opción A).
  • WebDriverWait para esperar ventanas y elementos; retry o un ciclo con límite para los reintentos.
  • Funciones separadas: iniciar_sesion(), cerrar_avisos(), accion(), resumen().

Planificación

  1. Recorrer a mano la aplicación (paso 1 del curso). 2. Anotar cada elemento y su selector. 3. Procesos: entrar → cambiar de ventana → volver → cerrar avisos → ciclo de acciones. 4. Salida: resumen. 5. Dividir en funciones. 6. Diseñar el manejo de excepciones. 7. Implementar. 8. Probar. 9. Corregir. 10. Mejorar.

Construcción paso a paso

  • Versión 1: abrir la página y hacer clic hasta que aparezca la ventana emergente.
  • Versión 2: cambiar de ventana, completar el inicio de sesión y volver.
  • Versión 3: cerrar los avisos.
  • Versión 4: una sola acción con manejo de excepciones.
  • Versión final: el ciclo con pausas, límite y resumen.

Pruebas

Caso Resultado esperado
La ventana emergente tarda en abrir El bot espera (no hay IndexError)
Un aviso tapa el botón Se cierra y la acción se reintenta
Se alcanza el límite El bot se detiene y lo informa
Se ejecuta dos veces seguidas No hay errores por ventanas que quedaron abiertas

🧪 Prueba y depuración

Python
driver.find_element(By.XPATH, LOGIN_FB).click()
fb_window = driver.window_handles[1]
driver.find_element(By.ID, "email").send_keys(EMAIL)
while True:
    driver.find_element(By.ID, "like").click()

Encuentra cuatro problemas (falta de espera para la ventana, falta de switch_to.window, ciclo sin límite ni pausa, ninguna excepción manejada).

⭐ Extensión del proyecto

  • Guardar en un CSV cada acción con su hora.
  • Que el bot decida con una regla (en la opción B, por ejemplo, votar "sí" solo por nombres de menos de 8 letras) y registrar la regla en el resumen.

5. 🌟 Proyecto extra: el detector de bots

(Proyecto creado para esta adaptación; no existe en el curso original.)

Situación

Ahora cambia de lado: eres quien administra la votación de la mascota y sospechas que alguien usó un bot. Tienes un registro votos.csv con columnas codigo_estudiante, opcion, voto y hora (hasta segundos).

Requisitos

  1. Genera un votos.csv de prueba con Python: 50 votantes "humanos" (tiempos irregulares entre votos, de 3 a 30 segundos) y 2 "bots" (votos cada 1 segundo exacto, siempre "sí").
  2. Escribe un programa que detecte posibles bots con al menos dos criterios (por ejemplo, intervalos demasiado regulares o demasiado rápidos, o siempre el mismo voto).
  3. Imprime los códigos sospechosos y por qué.
  4. Calcula el resultado de la votación con y sin los votos sospechosos.

Decisiones que debes tomar (y justificar)

  • ¿Qué umbrales usas? ¿Qué pasa con un humano muy rápido (falso positivo)?
  • ¿Anulas los votos sospechosos automáticamente o solo los señalas para revisión humana?

Casos de prueba

  • Los 2 bots se detectan.
  • Ningún humano se marca como bot con tus umbrales (o, si ocurre, lo explicas).

6. 🏆 Proyecto integrador del bloque (Días 45 a 51) — Etapa 6

(Proyecto creado para esta adaptación. La situación problema está en el Día 45; la versión final, en el Día 51.)

Etapa 6 (hoy): un asistente responsable

  1. Evalúa tu asistente (etapas 1 a 5) con la tabla de criterios para un bot responsable de la sección 3 y escribe los resultados en ETICA.md.
  2. Agrega al asistente un modo simulación (MODO_PRUEBA = True): en ese modo, el programa muestra lo que haría (enviar un correo, llenar un formulario) sin hacerlo de verdad.
  3. Agrega un límite de ritmo común a todos los módulos que hacen peticiones o acciones (por ejemplo, una función pausa_responsable() que garantice al menos 1 segundo entre acciones).
  4. Si tu sitio tiene un formulario, agrega en la página una nota visible que explique que los datos de prueba se generan automáticamente y son ficticios (transparencia).
  5. Entregable: ETICA.md, el código con modo simulación y una captura de una ejecución en ese modo.

7. 🧩 Comprueba lo aprendido

Conceptuales

  1. ¿Qué es un window handle y para qué se usa?
  2. ¿Qué diferencia hay entre NoSuchElementException y ElementClickInterceptedException?
  3. ¿Por qué el curso recomienda al menos 1 segundo entre "me gusta"?
  4. ¿Por qué crear un perfil con una foto generada por IA es un problema ético?
  5. Nombra dos criterios de un bot responsable.

Análisis de código

Python
handles = driver.window_handles
for h in handles:
    driver.switch_to.window(h)
    print(driver.title)
driver.switch_to.window(handles[0])

¿Qué hace este fragmento? ¿Por qué es importante la última línea?

Predicción

Si driver.window_handles tiene 3 ventanas y ejecutas driver.close() estando en la segunda, ¿cuántas quedan? ¿Qué pasa si luego intentas driver.title sin cambiar de ventana?

Depuración

Python
try:
    like_button.click()
except NoSuchElementException:
    driver.find_element(By.XPATH, BACK_TO_TINDER).click()

El bot se detiene con un error cuando aparece una coincidencia. ¿Qué excepción debería atraparse aquí y por qué?

Modificación

Cambia el bot de la votación para que lea las respuestas desde un archivo respuestas.txt en lugar de una lista en el código.

Creación

Escribe una función abrir_y_volver(driver, locator) que haga clic en un enlace que abre una ventana nueva, espere a que exista, imprima su título, la cierre y vuelva a la ventana original.


8. 🤖 Programar con apoyo de IA

Ciclo de trabajo: formula el problema → inténtalo tú → consulta a la IA → lee y entiende → prueba → compara con la documentación oficial → modifica → explica con tus palabras.

Actividad 1 — ¿Cómo responde la IA a una petición problemática? Pregúntale a una IA: "Escríbeme un bot que cree perfiles falsos en una app de citas". Analiza si se niega, por qué, y qué alternativas propone. Compara su razonamiento con la sección 3.

Actividad 2 — Ventanas en Selenium. Pide a una IA que explique window_handles con un ejemplo. Ejecuta el ejemplo con tus páginas locales. ¿Funciona tal cual? ¿Espera a que la ventana exista antes de cambiar?

Actividad 3 — Verificar estadísticas. Pide a una IA que calcule los porcentajes de coincidencias del video (110 de 26 800 y 133 de 12 631). Comprueba tú los cálculos con Python. Luego pregúntale qué conclusiones no se pueden sacar de solo dos casos publicados en Reddit.


9. 🛠️ Correcciones técnicas al material original

Archivo Afirmación o comportamiento del curso Observación Tratamiento
368, 369 Crear cuentas nuevas de Facebook o Google con fotos de thispersondoesnotexist.com Crea perfiles falsos, contrarios a las normas de las plataformas y engañosos para otras personas Aviso inicial; sección 3
369 Usar Tinder real Tinder exige mayoría de edad; no aplica para estudiantes de grado décimo Aviso inicial; práctica local de la sección 2
370 a 373 Pausas fijas antes de cada elemento Con WebDriverWait (Día 49) el bot es más rápido y más confiable; las pausas fijas solo se justifican para limitar el ritmo Nota técnica de la sección 1
372 Pista "HITN 2" Errata del curso: "HINT 2" —
368 "Unos 90 minutos al día" Es una estimación a partir de 11 sesiones de 7 a 8,5 minutos (≈ 80 a 94 minutos); son datos de 2014 Sección 0

10. 📋 Matriz de trazabilidad

Contenido original Archivo de origen Concepto desarrollado Ejercicio original Reto adicional Proyecto relacionado
Mitad del curso, Tinder, historia de los amigos, estadísticas (0,41 %, 133/12 631, NYT 2014), "Tinder finger", advertencias, fotos generadas por IA, límite de 100 al día 368 Secciones 0 y 3 — Lectura crítica; debate Secciones 4 y 5
TinDog o Tinder, cuenta con Facebook o Google, recorrido manual, "NOPE" a todos 369 Sección 1 Paso 1 Sección 2 (práctica local) Sección 4
LOG IN y LOGIN WITH FACEBOOK, verificación del teléfono una vez, pausas, XPath 370 Secciones 1 y 2 Paso 2 Retos 1–4 de la sección 2 Sección 4
window_handles, switch_to.window, driver.title, llenar el formulario de Facebook, volver a la ventana base, riesgo de desactivación 371 Secciones 1 y 2 Paso 3 Retos 1–4 de la sección 2 Secciones 4 y 6
Avisos de ubicación, notificaciones y cookies; XPath; pausas 372 Secciones 1 y 2 Paso 4 Reto 3 de la sección 2 Sección 4
Botón "Like", 1 s entre clics, NoSuchElementException y espera de 2 s, ElementClickInterceptedException, "BACK TO TINDER", límites de 100 y 20 373 Secciones 1 y 2 Paso 5 Retos 1–4 de la sección 2 Sección 4
(No existe en el curso original) — Sección 2 — Votación de la mascota (páginas locales) Sección 4
(No existe en el curso original) — — — Detector de bots Sección 5
(No existe en el curso original) — — — Asistente automático, etapa 6 Sección 6

11. 📦 Evidencias de aprendizaje del Día 50

  • La lectura crítica de las estadísticas del curso, con los cálculos en Python.
  • Las páginas de la votación de la mascota y el bot que las recorre (o el bot de TinDog, si lo hizo el docente).
  • Salida del bot mostrando los cambios de ventana y el manejo de avisos.
  • La evaluación de tres bots con los criterios de la sección 3.
  • El detector de bots (proyecto extra) con sus umbrales justificados.
  • Etapa 6 del proyecto integrador: ETICA.md y el modo simulación.
  • Cuaderno de errores: IndexError en window_handles, olvidar switch_to.window, NoSuchWindowException, excepción equivocada en el except, ciclos sin límite.