Skip to content

ocklham/biz_scrap

Repository files navigation

ChronoBot - Automatización de Fichaje en Bizneo

Bot automatizado inteligente para realizar el fichaje de entrada y salida en la plataforma Bizneo HR de Rock Internet.

📖 Descripción General

ChronoBot es un sistema automatizado que gestiona el fichaje horario en Bizneo HR usando web scraping con Playwright. El bot está diseñado para simular comportamiento humano y ejecutarse de forma autónoma en horarios aleatorios dentro de ventanas configurables.

🚀 Características Principales

✅ Automatización Inteligente

  • Login automático con gestión persistente de sesiones (evita logins repetidos)
  • Detección y gestión de reCAPTCHA con intervención manual asistida
  • Verificación de acción esperada: solo hace clic si el botón coincide con la tarea programada
  • Simulación de comportamiento humano: movimientos de ratón, delays aleatorios, velocidad de escritura variable

✅ Programación Avanzada

  • Horarios aleatorios dentro de rangos configurables (evita patrones predecibles)
  • Respeta días festivos y fines de semana (configurable por archivo JSON)
  • Sistema de reintentos automáticos cada 1 minuto ante fallos
  • Ejecución dual: mañana (entrada) y tarde (salida) con validación independiente

✅ Modos de Ejecución

  • Modo Manual: ejecución inmediata para pruebas y debugging
  • Modo Servicio: ejecución continua en segundo plano respetando horarios
  • Servicio Windows: instalación como servicio del sistema con inicio automático

✅ Auditoría y Debugging

  • Logging completo con niveles configurables (DEBUG, INFO, WARNING, ERROR)
  • Capturas de pantalla automáticas en puntos críticos y errores
  • Registro detallado de acciones (tomadas, saltadas, fallidas)
  • Trazabilidad completa de cada ejecución

🏗️ Arquitectura del Sistema

Componentes Principales

┌─────────────────────────────────────────────────────────────┐
│                        ChronoBot                             │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────────┐      ┌──────────────┐      ┌──────────┐  │
│  │  Scheduler   │─────▶│   Scraper    │─────▶│ Bizneo   │  │
│  │  (Horarios)  │      │  (Playwright)│      │   HR     │  │
│  └──────────────┘      └──────────────┘      └──────────┘  │
│         │                      │                             │
│         ▼                      ▼                             │
│  ┌──────────────┐      ┌──────────────┐                     │
│  │   Config     │      │  State Mgmt  │                     │
│  │  Holidays    │      │  (Sessions)  │                     │
│  └──────────────┘      └──────────────┘                     │
│         │                      │                             │
│         ▼                      ▼                             │
│  ┌─────────────────────────────────────┐                    │
│  │        Logging & Screenshots        │                    │
│  └─────────────────────────────────────┘                    │
│                                                              │
└─────────────────────────────────────────────────────────────┘

1. Scheduler (src/scheduler.py)

Responsabilidad: Gestión de tareas programadas y control de horarios

Funcionalidades:

  • Genera horarios aleatorios diarios dentro de ventanas configuradas
  • Verifica días laborables (excluye festivos y fines de semana)
  • Controla ejecución única por ventana horaria
  • Resetea flags automáticamente al cambiar de día
  • Ejecuta verificaciones cada 1 minuto
  • Implementa sistema de reintentos ante fallos

Lógica de Ejecución:

# Cada minuto verifica:
1. ¿Es un día laborable? → Si no, skip
2. ¿Ya se ejecutó esta tarea hoy? → Si , skip
3. ¿Es el momento exacto programado? → Si no, wait
4. ¿La tarea tuvo éxito? → Marcar como ejecutada / Si no, permitir reintento

Ventanas Horarias:

  • Mañana: Rango configurable (ej: 08:30-09:10) → Acción esperada: "Iniciar"
  • Tarde: Rango configurable (ej: 18:00-19:00) → Acción esperada: "Finalizar"

2. Scraper (src/scraper.py)

Responsabilidad: Automatización de interacción web con Playwright

Funcionalidades:

  • Gestión de navegador: Chromium con configuración anti-detección
  • Manejo de sesiones: Carga/guarda estado para evitar logins repetidos
  • Proceso de login:
    • Detección automática si ya está logueado
    • Relleno de formulario con delays humanos
    • Detección de reCAPTCHA
    • Espera asistida para resolución manual de CAPTCHA
    • Verificación activa de login exitoso
  • Clic inteligente en botón:
    • Localiza botón de Chrono
    • Verifica tipo de acción (Iniciar vs Finalizar)
    • Compara con acción esperada
    • Solo hace clic si coincide
    • Registra acción tomada o razón de omisión
  • Simulación humana:
    • Movimientos de ratón en curvas aleatorias
    • Delays variables entre acciones
    • Velocidad de escritura realista

Flujo de Autenticación:

1. Navegar a URL → Wait networkidle
2. ¿Ya logueado? → Sí: Skip login | No: Continuar
3. Delay inicial + movimientos de ratón (2-4s)
4. Click campo email → Escribir con delay (50-150ms por tecla)
5. Delay (500-1000ms)
6. Click campo password → Escribir con delay
7. Delay (800-1500ms)
8. ¿Hay reCAPTCHA? → Sí: Esperar resolución manual | No: Continuar
9. Click botón "Entrar"
10. Esperar y verificar login exitoso (hasta 40s)
11. Guardar estado de sesión

Flujo de Clic en Botón:

1. Delay inicial (1-2s)
2. Wait selector: button[data-gtm-category="chrono"]
3. Leer texto del botón
4. Determinar acción actual: "iniciar" | "finalizar" | "desconocido"
5. ¿Acción coincide con esperada?
   → SÍ: Simular movimiento ratón → Click → Return (success=True, action_taken=True)
   → NO: Screenshot → Return (success=True, action_taken=False)
6. Esperar procesamiento (3-5s)
7. Screenshot final

3. Utils (src/utils.py)

Responsabilidad: Utilidades transversales del sistema

Componentes:

  • Config: Carga y gestión de configuración desde JSON
  • HolidayChecker: Verificación de festivos y fines de semana
  • setup_logging: Configuración de sistema de logs
  • ensure_directories: Creación de directorios necesarios

4. Gestión de Estado (playwright-state/state.json)

Responsabilidad: Persistencia de sesión del navegador

Contenido:

  • Cookies de sesión
  • Local storage
  • Session storage
  • Origen y permisos

Ventajas:

  • Evita login en cada ejecución
  • Reduce exposición a CAPTCHA
  • Acelera el proceso
  • Mantiene sesión entre reinicios

🔄 Análisis Funcional: Flujos de Trabajo

Flujo 1: Ejecución Normal (Día Laborable)

07:00 → Scheduler inicia (run_service.py)
      │
      ├─ Genera horario aleatorio mañana: 08:47
      ├─ Genera horario aleatorio tarde: 18:23
      ├─ Log: próximas ejecuciones programadas
      │
08:00 → Loop cada 1 minuto
      │
08:47 → ¡Hora exacta alcanzada!
      ├─ Verifica: ¿Es laborable? ✓
      ├─ Verifica: ¿Ya ejecutada? ✗
      ├─ Llama: scraper.run(expected_action='iniciar')
      │   ├─ Navega a Bizneo
      │   ├─ Carga sesión guardada → Ya logueado ✓
      │   ├─ Busca botón Chrono
      │   ├─ Lee texto: "Iniciar" ✓
      │   ├─ Compara: esperado='iniciar', actual='iniciar' → Match ✓
      │   ├─ Simula mouse + Click
      │   └─ Return: {success: true, action_taken: true}
      ├─ Marca: morning_executed = True
      └─ Log: ✓ Tarea mañana completada
      │
18:23 → ¡Hora exacta alcanzada!
      ├─ Verifica: ¿Es laborable? ✓
      ├─ Verifica: ¿Ya ejecutada? ✗
      ├─ Llama: scraper.run(expected_action='finalizar')
      │   ├─ Navega a Bizneo
      │   ├─ Carga sesión guardada → Ya logueado ✓
      │   ├─ Busca botón Chrono
      │   ├─ Lee texto: "Finalizar" ✓
      │   ├─ Compara: esperado='finalizar', actual='finalizar' → Match ✓
      │   ├─ Simula mouse + Click
      │   └─ Return: {success: true, action_taken: true}
      ├─ Marca: evening_executed = True
      └─ Log: ✓ Tarea tarde completada
      │
00:00 → Nuevo día detectado
      ├─ Reset: morning_executed = False
      ├─ Reset: evening_executed = False
      └─ Genera nuevos horarios aleatorios

Flujo 2: Fichaje Manual Previo (Usuario ya fichó entrada)

08:00 → Usuario ficha entrada manualmente en Bizneo
      │
08:47 → Scheduler ejecuta tarea mañana
      ├─ Llama: scraper.run(expected_action='iniciar')
      │   ├─ Navega a Bizneo
      │   ├─ Ya logueado ✓
      │   ├─ Busca botón Chrono
      │   ├─ Lee texto: "Finalizar" (porque ya está iniciado)
      │   ├─ Compara: esperado='iniciar', actual='finalizar' → No match ✗
      │   ├─ Screenshot: 'skipped_finalizar'
      │   └─ Return: {success: true, action_taken: false}
      ├─ Marca: morning_executed = True (evita reintentos)
      └─ Log: ⏭️ Ejecutada sin acción: botón es "finalizar" pero se esperaba "iniciar"
      │
18:23 → Scheduler ejecuta tarea tarde
      ├─ Llama: scraper.run(expected_action='finalizar')
      │   ├─ Navega a Bizneo
      │   ├─ Busca botón Chrono
      │   ├─ Lee texto: "Finalizar" ✓
      │   ├─ Compara: esperado='finalizar', actual='finalizar' → Match ✓
      │   └─ Click exitoso → Ficha salida
      └─ Log: ✓ Tarea tarde completada

Flujo 3: Fallo de Red con Reintentos

08:47 → Scheduler ejecuta tarea mañana
      ├─ Llama: scraper.run(expected_action='iniciar')
      │   ├─ Navega a Bizneo
      │   └─ ERROR: Timeout (red caída)
      ├─ Return: {success: false}
      ├─ NO marca morning_executed (permite reintento)
      └─ Log: ✗ Tarea mañana falló: Timeout, se reintentará
      │
08:48 → Loop ejecuta tarea mañana (reintento automático)
      ├─ Verifica: ¿Ya ejecutada? ✗ (porque falló)
      ├─ ¿Es hora exacta? ✗ (pero sigue en ventana)
      └─ Skip (espera minuto exacto)
      │
[La red se recupera]
      │
08:49 → Loop ejecuta tarea mañana
      ├─ Ahora está fuera del minuto exacto programado (08:47)
      ├─ Pero morning_executed = False
      └─ En implementación actual: solo intenta en minuto exacto
      
NOTA: Sistema actual intenta solo en minuto aleatorio programado.
      Para reintentos continuos durante toda la ventana,
      necesitaría modificar lógica de verificación de tiempo.

Flujo 4: Detección de reCAPTCHA

Primera ejecución del día (sesión expirada):
      │
08:47 → Scheduler ejecuta tarea mañana
      ├─ Llama: scraper.run(expected_action='iniciar')
      │   ├─ Navega a Bizneo
      │   ├─ No hay sesión válida → Login necesario
      │   ├─ Rellena email + password
      │   ├─ DETECTA reCAPTCHA ⚠️
      │   ├─ Log: ⚠️ CAPTCHA DETECTADO
      │   ├─ Muestra mensaje en consola
      │   ├─ Espera resolución manual (hasta 3 min)
      │   │   └─ Loop: verifica cada 2s si ya está logueado
      │   ├─ Usuario resuelve CAPTCHA + hace login
      │   ├─ Bot detecta login exitoso ✓
      │   ├─ Guarda nueva sesión
      │   ├─ Continúa: busca botón y hace clic
      │   └─ Return: {success: true, action_taken: true}
      └─ Log: ✓ Login completado manualmente (con CAPTCHA)
      │
Siguientes ejecuciones:
      │
      └─ Usa sesión guardada → Sin CAPTCHA ✓

🔁 Sistema de Reintentos

Estrategia de Reintentos

Nivel 1: Reintentos dentro del login

  • Contexto: Después de hacer clic en "Entrar"
  • Frecuencia: Cada 2 segundos
  • Duración: Hasta 40 segundos (20 intentos)
  • Verifica: Si el login fue exitoso o hay mensaje de error

Nivel 2: Reintentos de tarea completa

  • Contexto: Si la tarea falla por cualquier motivo
  • Frecuencia: Cada 1 minuto (siguiente ciclo del scheduler)
  • Duración: Mientras esté en la ventana horaria Y no se haya ejecutado exitosamente
  • Condición: Solo en el minuto aleatorio programado

Tabla de Resultados y Comportamiento

Resultado success action_taken morning_executed Comportamiento
Click exitoso ✅ true ✅ true ✅ true No reintenta
Botón incorrecto ✅ true ❌ false ✅ true No reintenta (acción correcta)
Error de red ❌ false ❌ false ❌ false Reintenta siguiente minuto
Timeout login ❌ false ❌ false ❌ false Reintenta siguiente minuto
Error CAPTCHA ❌ false ❌ false ❌ false Reintenta siguiente minuto
Botón no encontrado ❌ false ❌ false ❌ false Reintenta siguiente minuto

Limitación Actual del Sistema de Reintentos

⚠️ IMPORTANTE: El sistema actual solo intenta ejecutar en el minuto aleatorio programado. Si falla en ese minuto y la red se recupera después, NO reintentará hasta el día siguiente.

Ejemplo:

  • Hora programada: 08:47
  • Intento a las 08:47 → Falla (red caída)
  • Red se recupera a las 08:50
  • Resultado: NO reintenta (espera hasta 08:47 del día siguiente)

Solución potencial (no implementada):

# En lugar de verificar minuto exacto:
if (current_time.hour == self.morning_target_time.hour and 
    current_time.minute == self.morning_target_time.minute):
    
# Podría verificar si está dentro de la ventana:
if self._is_time_in_range(current_time, morning_config['start_time'], 
                           morning_config['end_time']):

⚙️ Configuración Detallada

Archivo config.json

El archivo de configuración controla todos los aspectos del comportamiento del bot:

{
  "credentials": {
    "email": "tu.email@empresa.com",
    "password": "tu_contraseña_aqui"
  },
  "schedule": {
    "morning": {
      "enabled": true,
      "start_time": "08:30",
      "end_time": "09:10"
    },
    "evening": {
      "enabled": true,
      "start_time": "18:00",
      "end_time": "19:00"
    },
    "timezone": "Europe/Madrid"
  },
  "platform": {
    "url": "https://rockinternet.bizneohr.com",
    "timeout": 30000
  },
  "browser": {
    "headless": true,
    "save_state": true,
    "state_file": "playwright-state/state.json",
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."
  },
  "logging": {
    "enabled": true,
    "log_file": "logs/chrono_bot.log",
    "level": "INFO"
  }
}

Sección: credentials

Parámetro Tipo Descripción
email string Email de acceso a Bizneo HR
password string Contraseña de acceso a Bizneo HR

Sección: schedule

Parámetro Tipo Default Descripción
morning.enabled boolean true Habilita ejecución matutina
morning.start_time string "08:30" Inicio ventana horaria (formato HH:MM)
morning.end_time string "09:10" Fin ventana horaria
evening.enabled boolean true Habilita ejecución vespertina
evening.start_time string "18:00" Inicio ventana horaria
evening.end_time string "19:00" Fin ventana horaria
timezone string "Europe/Madrid" Zona horaria (lista IANA)

Nota sobre horarios aleatorios:

  • El bot genera un minuto aleatorio dentro de cada ventana
  • Ejemplo: ventana 08:30-09:10 → podría ejecutar a las 08:47
  • Se regenera diariamente para evitar patrones

Sección: platform

Parámetro Tipo Default Descripción
url string - URL de Bizneo HR
timeout integer 30000 Timeout para operaciones (milisegundos)

Sección: browser

Parámetro Tipo Default Descripción
headless boolean true true: navegador invisible, false: navegador visible
save_state boolean true Guardar sesión para evitar login repetido
state_file string "playwright-state/state.json" Ruta del archivo de estado
user_agent string (ver config) User-Agent del navegador

Modos headless:

  • Producción: headless: true (invisible, menos recursos)
  • Debugging: headless: false (ver navegador en acción)
  • CAPTCHA: Automáticamente se muestra el navegador si detecta CAPTCHA

Sección: logging

Parámetro Tipo Default Descripción
enabled boolean true Habilita logging a archivo
log_file string "logs/chrono_bot.log" Ruta del archivo de log
level string "INFO" Nivel: DEBUG, INFO, WARNING, ERROR

Niveles de logging:

  • DEBUG: Máximo detalle (incluye verificaciones cada minuto)
  • INFO: Operaciones normales y resultados
  • WARNING: Acciones saltadas, reintentos
  • ERROR: Fallos y excepciones

Archivo days/holidays.json

Define los días festivos en los que el bot NO ejecutará:

{
  "holidays": [
    {"date": "2025-01-01", "name": "Año Nuevo"},
    {"date": "2025-01-06", "name": "Reyes Magos"},
    {"date": "2025-05-01", "name": "Día del Trabajador"},
    {"date": "2025-08-15", "name": "Asunción de la Virgen"},
    {"date": "2025-10-12", "name": "Día de la Hispanidad"},
    {"date": "2025-11-01", "name": "Todos los Santos"},
    {"date": "2025-12-06", "name": "Día de la Constitución"},
    {"date": "2025-12-08", "name": "Inmaculada Concepción"},
    {"date": "2025-12-25", "name": "Navidad"}
  ]
}

Nota: Los fines de semana se detectan automáticamente (no es necesario añadirlos).

Para actualizar festivos:

python update_holidays.py

📋 Requisitos

  • Python 3.8 o superior
  • Windows 10/11 (para instalación como servicio)
  • Conexión a internet estable
  • Chromium (se instala automáticamente con Playwright)

🔧 Instalación

1. Clonar o descargar el repositorio

git clone <url-del-repositorio>
cd biz_scrap

2. Crear entorno virtual (recomendado)

python -m venv venv
venv\Scripts\activate

3. Instalar dependencias

pip install -r requirements.txt

4. Instalar navegadores de Playwright

python -m playwright install chromium

5. Configurar credenciales

  1. Copia el archivo de configuración de ejemplo:

    copy config.json.sample config.json
  2. Edita config.json con tus credenciales y ajusta los horarios según tu necesidad:

    {
      "credentials": {
        "email": "tu.email@empresa.com",
        "password": "tu_contraseña"
      },
      "schedule": {
        "morning": {
          "start_time": "08:30",
          "end_time": "09:10"
        },
        "evening": {
          "start_time": "18:00",
          "end_time": "19:00"
        }
      }
    }

6. Configurar días festivos

Actualiza los festivos del año actual:

python update_holidays.py

O edita manualmente days/holidays.json con los festivos de tu localidad.

🎯 Uso

Modo Manual (Pruebas y Debugging)

Para ejecutar el bot manualmente y verificar que funciona:

python run_manual.py

Características de este modo:

  • ✅ Ejecuta inmediatamente (sin esperar horarios)
  • ✅ Hace clic en cualquier botón disponible (sin validar acción esperada)
  • ✅ Ejecuta incluso en festivos y fines de semana
  • ✅ Ideal para pruebas iniciales y verificación de configuración
  • ✅ Útil para debugging con headless: false

Casos de uso:

  • Primera configuración: verificar credenciales
  • Resolver CAPTCHA inicial y guardar sesión
  • Debugging de problemas
  • Fichaje manual cuando el servicio no está activo

Modo Servicio (Producción)

Para ejecutar el bot como un proceso permanente:

python run_service.py

Características de este modo:

  • ✅ Ejecución continua en segundo plano
  • ✅ Respeta horarios aleatorios configurados
  • ✅ Valida acción esperada (mañana=Iniciar, tarde=Finalizar)
  • ✅ No ejecuta en festivos ni fines de semana
  • ✅ Sistema de reintentos automático
  • ✅ Logging completo de todas las operaciones

Control del servicio:

# Detener (en la misma terminal)
Ctrl+C

# Ver logs en tiempo real (en otra terminal)
Get-Content logs\chrono_bot.log -Wait -Tail 20

Instalación como Servicio de Windows

Para que el bot se ejecute automáticamente al iniciar Windows:

  1. Abrir PowerShell como Administrador

  2. Navegar al directorio del proyecto

    cd C:\ruta\a\biz_scrap
  3. Activar el entorno virtual

    venv\Scripts\activate
  4. Instalar el servicio

    python install_windows_service.py install
  5. Iniciar el servicio

    net start ChronoBotService

Otros comandos del servicio:

# Detener el servicio
net stop ChronoBotService

# Desinstalar el servicio
python install_windows_service.py uninstall

# Ver estado en el Administrador de Servicios
services.msc

🛠️ Scripts de Utilidad

El proyecto incluye varios scripts para facilitar la gestión:

run_manual.py - Ejecución Manual

python run_manual.py

Ejecuta el bot inmediatamente sin restricciones de horario.

run_service.py - Servicio Programado

python run_service.py

Ejecuta el bot como servicio permanente respetando horarios.

clear_session.py - Limpiar Sesión

python clear_session.py

Elimina la sesión guardada. Útil cuando:

  • Cambias de contraseña en Bizneo
  • La sesión está corrupta
  • Quieres forzar un nuevo login

update_holidays.py - Actualizar Festivos

python update_holidays.py

Herramienta interactiva para actualizar festivos del año:

  • Genera festivos nacionales de España automáticamente
  • Permite añadir festivos locales/autonómicos
  • Muestra resumen con día de la semana
  • Valida formato de fechas

test_connection.py - Verificar Conexión

python test_connection.py

Verifica que se puede acceder a Bizneo HR (si existe en el proyecto).

📊 Logs y Debugging

Sistema de Logging

El bot registra todas sus operaciones en logs/chrono_bot.log con formato:

2025-10-09 08:47:23 - ChronoBot.Scheduler - INFO - 🌅 ¡Hora programada alcanzada! Ejecutando tarea de la MAÑANA
2025-10-09 08:47:28 - ChronoBot.Scraper - INFO - Botón encontrado: 'iniciar'
2025-10-09 08:47:35 - ChronoBot.Scraper - INFO - ✓ Clic realizado exitosamente en botón 'iniciar'

Comandos para Ver Logs

# Ver últimas 50 líneas
Get-Content logs\chrono_bot.log -Tail 50

# Ver logs en tiempo real
Get-Content logs\chrono_bot.log -Wait -Tail 20

# Buscar ejecuciones de hoy
Select-String -Path logs\chrono_bot.log -Pattern "2025-10-09"

# Buscar solo errores
Select-String -Path logs\chrono_bot.log -Pattern "ERROR"

# Buscar acciones completadas
Select-String -Path logs\chrono_bot.log -Pattern "Clic realizado"

# Buscar acciones saltadas
Select-String -Path logs\chrono_bot.log -Pattern "SALTANDO clic"

Capturas de Pantalla Automáticas

El bot toma capturas en momentos clave guardadas en screenshots/:

Nombre Momento Descripción
before_login_YYYYMMDD_HHMMSS.png Antes de login Formulario rellenado
captcha_detected_*.png Si detecta CAPTCHA Para verificar detección
after_login_success_*.png Login exitoso Confirmación de sesión
before_click_*.png Antes de clic Botón localizado
after_click_iniciar_*.png Después de clic Confirmación de entrada
after_click_finalizar_*.png Después de clic Confirmación de salida
skipped_*.png Acción saltada Botón no coincide
*_error_*.png En errores Captura del problema

Modo Debugging

Para ver el navegador en acción y diagnosticar problemas:

  1. Edita config.json:
{
  "browser": {
    "headless": false
     },
     "logging": {
       "level": "DEBUG"
  }
}
  1. Ejecuta en modo manual:

    python run_manual.py
  2. Observa el navegador ejecutando las acciones

  3. Revisa logs con nivel DEBUG para máximo detalle

Interpretación de Logs

✅ Ejecución Exitosa

INFO - 🌅 ¡Hora programada alcanzada! Ejecutando tarea de la MAÑANA
INFO - Sesión activa detectada, omitiendo login
INFO - Botón encontrado: 'iniciar'
INFO - ✓ Procederemos a hacer clic: acción esperada 'iniciar' coincide
INFO - ✓ Clic realizado exitosamente en botón 'iniciar'
INFO - ✓ Tarea de la mañana completada: Clic realizado en botón "iniciar"

⏭️ Acción Saltada (Normal)

INFO - 🌅 Ejecutando tarea de la MAÑANA (esperando botón INICIAR)
INFO - Botón encontrado: 'finalizar'
WARNING - ⏭️ SALTANDO clic: se esperaba 'iniciar' pero el botón es 'finalizar'
WARNING - ⏭️ Tarea de la mañana ejecutada sin acción

Interpretación: Ya habías fichado entrada manualmente.

❌ Error que Reintentará

ERROR - Timeout durante el login: Navigation timeout of 30000 ms exceeded
WARNING - ✗ Tarea de la mañana falló: Error: Timeout, se reintentará

Interpretación: Problema temporal, reintentará en 1 minuto.

📁 Estructura del Proyecto

biz_scrap/
├── src/                           # Código fuente principal
│   ├── __init__.py                # Inicializador del paquete
│   ├── utils.py                   # 📦 Config, HolidayChecker, logging
│   ├── scraper.py                 # 🌐 BizneoScraper - Playwright automation
│   └── scheduler.py               # ⏰ ChronoScheduler - Tareas programadas
│
├── days/                          # Configuración de calendario
│   └── holidays.json              # 📅 Días festivos (editables)
│
├── logs/                          # Registro de operaciones
│   └── chrono_bot.log             # 📝 Log principal (auto-generado)
│
├── screenshots/                   # Capturas de debugging
│   └── *.png                      # 📸 Screenshots automáticos
│
├── playwright-state/              # Persistencia de sesión
│   └── state.json                 # 🔐 Sesión del navegador (auto-generado)
│
├── venv/                          # Entorno virtual Python
│   └── ...                        # (no incluir en git)
│
├── run_manual.py                  # 🚀 Ejecución manual inmediata
├── run_service.py                 # 🔄 Servicio programado continuo
├── install_windows_service.py     # ⚙️ Instalador servicio Windows
├── clear_session.py               # 🗑️ Limpiar sesión guardada
├── update_holidays.py             # 📆 Actualizar festivos
├── test_connection.py             # 🔍 Verificar conectividad (opcional)
│
├── config.json                    # ⚠️ Configuración (NO subir a git)
├── config.json.sample             # 📋 Plantilla de configuración
├── requirements.txt               # 📦 Dependencias Python
├── .gitignore                     # 🚫 Exclusiones de git
├── README.md                      # 📖 Esta documentación
├── FUNCIONAMIENTO.md              # 📘 Guía de funcionamiento detallada
├── INSTALL.md                     # 📗 Guía de instalación (si existe)
└── QUICK_START.md                 # ⚡ Guía rápida (si existe)

Descripción de Archivos Clave

Core del Sistema

  • src/scraper.py (570 líneas): Motor principal de automatización con Playwright

    • Gestión de navegador y sesiones
    • Login con detección de CAPTCHA
    • Clic inteligente en botones
    • Simulación de comportamiento humano
  • src/scheduler.py (282 líneas): Sistema de programación de tareas

    • Generación de horarios aleatorios
    • Control de días laborables
    • Sistema de reintentos
    • Gestión de ejecución dual (mañana/tarde)
  • src/utils.py (125 líneas): Utilidades compartidas

    • Clase Config para gestión de configuración
    • HolidayChecker para validación de festivos
    • Setup de logging
    • Creación de directorios

Scripts de Ejecución

  • run_manual.py: Ejecución única sin restricciones
  • run_service.py: Servicio continuo con scheduler
  • install_windows_service.py: Instalador de servicio Windows

Configuración

  • config.json: Configuración activa (credenciales, horarios, opciones)
  • days/holidays.json: Lista de festivos del año
  • playwright-state/state.json: Sesión del navegador (cookies, storage)

Archivos Generados

  • logs/chrono_bot.log: Registro de todas las operaciones
  • screenshots/*.png: Capturas de pantalla automáticas

🔒 Seguridad

  • ⚠️ NUNCA subas config.json a GitHub o repositorios públicos
  • El archivo .gitignore ya lo excluye automáticamente
  • Usa contraseñas fuertes y únicas
  • Revisa periódicamente los logs de acceso

🐛 Solución de Problemas

Problemas de Configuración

❌ Error: "No se encontró el archivo de configuración"

Síntoma: FileNotFoundError: No se encontró el archivo de configuración: config.json

Solución:

# Copiar plantilla
copy config.json.sample config.json

# Editar con tus credenciales
notepad config.json

❌ Error: "Credenciales no configuradas"

Síntoma: El bot se detiene indicando que faltan credenciales

Solución: Verifica que config.json tiene email y password configurados:

{
  "credentials": {
    "email": "tu.email@empresa.com",
    "password": "tu_contraseña_real"
  }
}

Problemas de Instalación

❌ Error: "playwright not found"

Solución completa:

# 1. Instalar dependencias
pip install -r requirements.txt

# 2. Instalar navegadores de Playwright
python -m playwright install chromium

# 3. Verificar instalación
python -m playwright --version

❌ Error: "ModuleNotFoundError"

Síntoma: No encuentra módulos como schedule, pytz, etc.

Solución:

# Verifica que estás en el entorno virtual
venv\Scripts\activate

# Reinstala dependencias
pip install -r requirements.txt

Problemas de Ejecución

❌ El bot no hace clic en el botón

Diagnóstico paso a paso:

  1. Ver navegador en acción:

    // config.json
    {
      "browser": {"headless": false},
      "logging": {"level": "DEBUG"}
    }
  2. Ejecutar en modo manual:

    python run_manual.py
  3. Revisar capturas:

    • Ve a screenshots/
    • Busca la última captura before_click_*.png
    • ¿Se ve el botón en la página?
  4. Verificar logs:

    Select-String -Path logs\chrono_bot.log -Pattern "Botón encontrado"

Posibles causas y soluciones:

Causa Síntoma en logs Solución
Sesión expirada "No se pudo completar el login" python clear_session.py + ejecutar de nuevo
Selector cambió "No se encontró el botón (timeout)" Contactar IT (selectores cambiaron en Bizneo)
Red lenta "Timeout" Aumentar timeout en config.json a 60000
Página cargando "Botón no encontrado" Ejecutar de nuevo (red lenta)

❌ Aparece CAPTCHA cada vez

Síntoma: reCAPTCHA en cada ejecución, no guarda la sesión

Diagnóstico:

# ¿Existe el archivo de estado?
dir playwright-state\state.json

# ¿Tiene permisos de escritura?

Soluciones:

  1. Verificar configuración:

    {
      "browser": {
        "save_state": true,  // ← Debe ser true
        "state_file": "playwright-state/state.json"
      }
    }
  2. Limpiar y regenerar sesión:

    python clear_session.py
    python run_manual.py  # Resuelve CAPTCHA, guarda sesión
    python run_service.py  # Ahora usará sesión guardada
  3. Verificar permisos:

    • Asegúrate de que la carpeta playwright-state/ tiene permisos de escritura

⏭️ El bot dice "SALTANDO clic" pero debería hacer clic

Síntoma: En logs aparece "se esperaba 'iniciar' pero el botón es 'finalizar'"

Interpretación: Esto es comportamiento normal, significa que:

  • Mañana: Ya habías fichado entrada manualmente → El botón ya es "Finalizar"
  • Tarde: Olvidaste fichar entrada → El botón aún es "Iniciar"

Acción:

  • Si es mañana y ya fichaste: ✅ Todo bien, no necesita hacer nada
  • Si es tarde y no fichaste entrada: ⚠️ Ficha entrada y salida manualmente

Problemas con Servicio Windows

❌ El servicio no instala

Síntoma: "Error al instalar servicio: Access denied"

Solución:

# 1. Cerrar terminal actual
# 2. Abrir PowerShell como Administrador (clic derecho > Ejecutar como administrador)
# 3. Navegar al proyecto
cd C:\ruta\a\biz_scrap

# 4. Activar entorno virtual
venv\Scripts\activate

# 5. Instalar servicio
python install_windows_service.py install

❌ El servicio no inicia

Diagnóstico:

  1. Ver estado del servicio:

    Get-Service ChronoBotService
  2. Ver logs del sistema:

    • Abrir eventvwr.msc (Visor de Eventos)
    • Ir a: Registros de Windows → Aplicación
    • Buscar eventos de "ChronoBotService"
  3. Verificar rutas:

    # El servicio debe ejecutarse desde el directorio del proyecto
    # Verifica que config.json existe en la ruta

Soluciones comunes:

# Detener servicio (si está corriendo)
net stop ChronoBotService

# Desinstalar servicio
   python install_windows_service.py uninstall

# Reinstalar servicio
   python install_windows_service.py install

# Iniciar servicio
net start ChronoBotService

# Ver estado
sc query ChronoBotService

Problemas de Red

🌐 Error: "Timeout" o "Connection refused"

Causas posibles:

  • Internet caído temporalmente
  • VPN desconectada (si es necesaria)
  • Firewall bloqueando conexión
  • Bizneo HR temporalmente inaccesible

Solución:

  1. Verificar conectividad:

    ping rockinternet.bizneohr.com
  2. El bot reintentará automáticamente cada 1 minuto durante la ventana horaria

  3. Si persiste, ejecutar manualmente más tarde:

    python run_manual.py

Problemas de Horarios

⏰ El bot no ejecuta a la hora esperada

Diagnóstico:

  1. Ver horarios programados:

    # Buscar en logs la línea de horarios
    Select-String -Path logs\chrono_bot.log -Pattern "Hora aleatoria generada"

    Ejemplo de salida:

    🎲 Hora aleatoria generada para MAÑANA: 08:47
    🎲 Hora aleatoria generada para TARDE: 18:23
    
  2. Verificar zona horaria:

    // config.json
    {
      "schedule": {
        "timezone": "Europe/Madrid"  // ← Verifica que es correcta
      }
    }
  3. Verificar día laborable:

    # ¿Es festivo o fin de semana?
    Select-String -Path logs\chrono_bot.log -Pattern "festivo"

Nota: El bot ejecuta en un minuto aleatorio dentro de la ventana, no al inicio de la ventana.

Otros Problemas

🔑 Cambié mi contraseña de Bizneo

Solución completa:

# 1. Actualizar config.json con nueva contraseña
notepad config.json

# 2. Limpiar sesión antigua
python clear_session.py

# 3. Generar nueva sesión
python run_manual.py

📸 No se generan capturas de pantalla

Verificar:

# ¿Existe la carpeta?
dir screenshots

# Si no existe, crearla
mkdir screenshots

# Ejecutar de nuevo
python run_manual.py

💾 El log crece mucho

Solución: Rotar logs periódicamente

# Hacer backup del log actual
copy logs\chrono_bot.log logs\chrono_bot_backup_$(Get-Date -Format 'yyyyMMdd').log

# Vaciar log actual
Clear-Content logs\chrono_bot.log

Mejor solución: Configurar rotación automática (future enhancement)

💡 Consejos y Mejores Prácticas

Para Uso Diario

  1. Revisa los logs semanalmente para asegurarte de que todo funciona
  2. Verifica en Bizneo que los fichajes se registraron correctamente
  3. Mantén el PC encendido durante las ventanas horarias programadas
  4. Actualiza festivos al inicio de cada año: python update_holidays.py

Para Debugging

  1. Usa modo manual (run_manual.py) para pruebas rápidas
  2. Activa headless: false solo cuando necesites ver el navegador
  3. Cambia a nivel DEBUG temporalmente para más detalles
  4. Revisa capturas en screenshots/ ante problemas

Para Producción

  1. Usa el servicio Windows para máxima confiabilidad
  2. Configura inicio automático con el equipo
  3. Mantén headless: true para menor consumo de recursos
  4. Revisa logs periódicamente para detectar problemas tempranos

Respaldos

# Backup de configuración
copy config.json config.json.backup

# Backup de festivos
copy days\holidays.json days\holidays.json.backup

# Backup de sesión (si funciona bien)
copy playwright-state\state.json playwright-state\state.json.backup

📝 Notas Importantes

Comportamiento del Sistema

  • Horarios aleatorios: El bot ejecuta en un minuto aleatorio dentro de cada ventana horaria (no al inicio)
  • 🎲 Regeneración diaria: Los horarios se generan nuevos cada día para evitar patrones
  • Ejecución única: Solo se ejecuta una vez por ventana horaria (mañana y tarde)
  • 📅 Días laborables: No se ejecuta en fines de semana ni festivos configurados
  • 🔐 Sesiones persistentes: Guarda la sesión para evitar logins y CAPTCHAs repetidos
  • 🔁 Reintentos automáticos: Si falla, reintenta cada 1 minuto (solo en el minuto programado)

Validación de Acciones

  • 🌅 Mañana: Solo hace clic si el botón es "Iniciar" (entrada)
  • 🌆 Tarde: Solo hace clic si el botón es "Finalizar" (salida)
  • ⏭️ Acciones saltadas: Si el botón no coincide con lo esperado, se registra pero no hace clic
  • 📝 Trazabilidad: Todas las acciones (tomadas, saltadas, fallidas) se registran en logs

Limitaciones Conocidas

  1. Reintentos limitados al minuto programado: Si falla a las 08:47 y la red se recupera a las 08:50, NO reintenta (espera al día siguiente)
  2. Requiere PC encendido: El bot solo funciona si el PC está encendido durante las ventanas horarias
  3. CAPTCHA manual: Si aparece reCAPTCHA, requiere resolución manual (el bot espera hasta 3 minutos)
  4. No detecta cambios en Bizneo: Si Bizneo cambia los selectores HTML, el bot puede dejar de funcionar (requiere actualización)

Dependencias del Sistema

  • Python 3.8+: Lenguaje de programación
  • Playwright: Automatización de navegador Chromium
  • schedule: Programación de tareas
  • pytz: Manejo de zonas horarias
  • pywin32: Integración con servicios de Windows (solo para servicio Windows)

🔗 Referencias

Documentación Adicional

  • FUNCIONAMIENTO.md: Guía detallada del funcionamiento interno con ejemplos de logs
  • config.json.sample: Plantilla con todos los parámetros disponibles
  • requirements.txt: Lista completa de dependencias con versiones

Recursos Externos

🆘 Soporte

Antes de Contactar Soporte

  1. Revisa logs: logs/chrono_bot.log
  2. Revisa capturas: screenshots/
  3. Consulta esta documentación: Especialmente sección "Solución de Problemas"
  4. Intenta modo manual: python run_manual.py con headless: false

Información a Proporcionar

Si necesitas ayuda, incluye:

  • 📋 Versión de Python: python --version
  • 📋 Sistema operativo: ver (Windows)
  • 📋 Últimas líneas del log (sin credenciales)
  • 📋 Capturas de pantalla del problema
  • 📋 Configuración (sin contraseña)

Contacto

Para reportar problemas, sugerencias o mejoras:

  • 📧 Contacta con el equipo de IT de Rock Internet
  • 📝 Describe el problema con el máximo detalle posible
  • 📎 Adjunta logs y capturas relevantes

📄 Licencia y Uso

Licencia: Uso interno de Rock Internet SL

Restricciones:

  • ⚠️ Esta herramienta es para uso exclusivo de empleados de Rock Internet
  • ⚠️ No distribuir fuera de la organización
  • ⚠️ No modificar sin autorización del equipo de IT
  • ⚠️ Usar de acuerdo con las políticas de la empresa

⚠️ Disclaimer

Esta herramienta está diseñada para automatizar tareas repetitivas de fichaje horario. Es responsabilidad del usuario:

  • ✅ Verificar que los fichajes se registren correctamente en Bizneo
  • ✅ Tener un sistema de respaldo manual en caso de fallo
  • ✅ Mantener la confidencialidad de las credenciales
  • ✅ Usar conforme a las políticas empresariales y legislación vigente

El sistema NO garantiza fichajes 100% exitosos. Siempre verifica en Bizneo que el registro se completó correctamente.

📊 Estadísticas del Proyecto

  • Líneas de código: ~1000 líneas (Python)
  • Archivos fuente: 3 módulos principales (scraper, scheduler, utils)
  • Scripts auxiliares: 5 (manual, service, install, clear, update)
  • Dependencias: 5 principales (playwright, schedule, pytz, python-dateutil, pywin32)
  • Documentación: README (1200+ líneas), FUNCIONAMIENTO.md

🎯 Roadmap y Mejoras Futuras

Mejoras Planificadas

  • Reintentos continuos durante toda la ventana (no solo en minuto programado)
  • Rotación automática de logs (evitar crecimiento indefinido)
  • Notificaciones por email en caso de fallos persistentes
  • Dashboard web para monitoreo del estado
  • Configuración de múltiples usuarios (para gestores)
  • Tests automatizados para CI/CD
  • Detección automática de cambios en selectores de Bizneo
  • Modo de simulación (dry-run) sin hacer clic real

Contribuciones

Si tienes ideas para mejorar el sistema, contacta con el equipo de IT.


ChronoBot v1.0 - Rock Internet SL © 2025 Automatización inteligente de fichaje horario con Bizneo HR

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors