Modelo de fuente del Senado

La fuente de camara-senadores-mex no es una API pública formal. Es una combinación de rutas HTML y una vista AJAX usada por la interfaz del portal institucional.

El modelo de fuente se entiende mejor como un conjunto de anclas:

/66/
├── votacion/{id}
│   └── app/votaciones/functions/viewTableVot.php
└── senador/{id}

/66/: sitio vigente como contenedor operativo

El segmento /66/ funciona como puerta de entrada del sitio vigente. En la práctica permite acceder tanto a votaciones como a perfiles bajo una convención común de rutas.

No debe leerse como garantía de que todo contenido pertenece a la LXVI Legislatura. El repositorio documenta votaciones históricas de LX a LXVI accesibles bajo esa ruta. Por eso la legislatura de una votación se parsea desde el contenido cuando existe y, si falta, se infiere desde la fecha.

Página de votación

La página base de una votación tiene esta forma:

https://www.senado.gob.mx/66/votacion/{id}

El HTML puede contener metadatos temporales, por ejemplo:

<strong>LXIII LEGISLATURA<br>TERCER AÑO DE EJERCICIO<br>SEGUNDO PERIODO ORDINARIO</strong>
<strong>Jueves 22 de febrero de 2018</strong>

El parser extrae:

CampoRegla
legislatureNumeral romano en LEGISLATURA; si falta, inferencia por fecha.
yearOrdinal antes de AÑO DE EJERCICIO.
periodOrdinal antes de PERIODO, aceptando PERIODO y PERIODO ORDINARIO.
dateFecha en español transformada a formato ISO.

El HTML de la votación no se trata como fuente final de votos nominales. La decisión vigente es consultar siempre el endpoint AJAX asociado.

Endpoint AJAX de votos nominales

El endpoint vigente para los registros nominales es:

https://www.senado.gob.mx/66/app/votaciones/functions/viewTableVot.php

La solicitud actual se hace como POST, no como GET contractual:

method: POST
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Referer: https://www.senado.gob.mx/66/votacion/{id}
body: action=ajax&cell=1&order=DESC&votacion={id}&q=

La respuesta es HTML parcial con filas de tabla. Un patrón esperado es:

<tr>
  <td class="text-center">1</td>
  <td><a href="/66/votaciones/577#info">Sen. González Canto, Félix Arturo</a></td>
  <td><a href="/66/votaciones/577#info">PRI</a></td>
  <td class="text-center">PRO</td>
</tr>

De esa fila se deriva conceptualmente:

CampoFuente
senador_idNúmero extraído del href de la fila (/votaciones/{id}).
nombreTexto del enlace de nombre, limpiando prefijos y orden Apellido, Nombre.
partidoTexto de la tercera celda.
votoTexto de la cuarta celda, uniendo nodos de texto cuando hay fragmentos múltiples.

La respuesta AJAX es evidencia primaria para votos nominales, pero no una garantía de completitud absoluta. Si la fuente devuelve filas vacías, metadatos incompletos o respuestas parciales, esos límites deben quedar visibles en la base y en la validación.

Página de senador

Los perfiles disponibles se consultan con:

https://www.senado.gob.mx/66/senador/{id}

El spider considera válida una página cuando encuentra la sección de información del senador. A partir de ahí extrae campos observables:

CampoSelector / regla conceptual
nombreh2.nSenador, removiendo prefijo Senador / Senadora.
sexoInferido desde el prefijo cuando el sitio lo expone.
tipo_eleccionh3.tipoEleccion, normalizado a valores observados.
estadoh4.nEstadi.
urlURL de perfil visitada.

El portal /66/ no garantiza perfil histórico para todos los IDs detectados en votos. Esa ausencia no se corrige dentro del extractor: se persiste lo disponible y se cuenta lo faltante.

Modelo de confianza

La fuente se usa con una lectura conservadora:

  • /66/votacion/{id} aporta contexto y metadatos temporales.
  • viewTableVot.php aporta filas nominales mediante POST form-urlencoded.
  • /66/senador/{id} aporta perfiles solo cuando la página existe y contiene estructura válida.
  • Incapsula/WAF introduce variabilidad de acceso; una ausencia puede ser dato inexistente, perfil no publicado, bloqueo o respuesta incompleta.

Por eso el contrato del proyecto no es “todo lo que el portal podría saber”, sino “lo que el extractor puede observar, parsear, persistir y auditar sin inventar”.