| Title: | Buscador y Analizador de Diarios de Sesión del Parlamento Uruguayo |
|---|---|
| Description: | Busca sesiones parlamentarias por palabra clave en el sitio del Parlamento del Uruguay, descarga los diarios de sesión en PDF y analiza sus textos: frecuencia de términos, evolución en el tiempo y co-ocurrencias. La app se ejecuta en la máquina del usuario, condición necesaria para consultar el sitio oficial, que rechaza las conexiones desde fuera de Uruguay. |
| Authors: | Emiliano González [aut, cre] |
| Maintainer: | Emiliano González <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-10-06 12:26:18 UTC |
| Source: | https://github.com/EmilianoGonLas/diariosuy |
patron1 tienen a patron2 dentro de
ventana caracteres en el mismo texto (co-ocurrencia de proximidad).Cuenta cuántas menciones de patron1 tienen a patron2 dentro de
ventana caracteres en el mismo texto (co-ocurrencia de proximidad).
.contar_proximos(texto, patron1, patron2, ventana = 500L).contar_proximos(texto, patron1, patron2, ventana = 500L)
texto |
Texto normalizado (minúsculas, espacios simples) |
patron1 |
Regex del término principal |
patron2 |
Regex del término de cruce |
ventana |
Máx. distancia en caracteres para considerar "cercano" (default 500) |
Entero: cuántas menciones de patron1 tienen a patron2 "cerca"
Busca el último signo de puntuación en los max_pre caracteres anteriores
al match y empieza allí. Si no hay ninguno, toma desde el límite.
Cierra en el primer punto dentro de los max_total caracteres siguientes.
.extraer_fragmento(texto, s, e, max_pre = 90L, max_total = 230L).extraer_fragmento(texto, s, e, max_pre = 90L, max_total = 230L)
texto |
Texto normalizado |
s, e
|
Inicio y fin del match a destacar |
max_pre |
Máx. chars a buscar hacia atrás para inicio de oración (default 90) |
max_total |
Longitud máxima del fragmento (default 230) |
Lista con: ws (índice inicio), we (índice fin), text (el fragmento)
Usa pdftools::pdf_data() para obtener las coordenadas de cada palabra y reconstruir el texto leyendo primero la columna izquierda completa y luego la derecha, en lugar de ir línea a línea de izquierda a derecha. Si pdf_data() falla, cae en pdf_text() como fallback.
.extraer_texto_pdf(ruta).extraer_texto_pdf(ruta)
ruta |
Ruta al archivo PDF |
Character vector con el texto de cada página (largo = n° de páginas)
Ordena por (y, x), detecta saltos de línea por el Δy entre palabras consecutivas y une las palabras de cada línea con espacios.
.reconstruir_columna(datos).reconstruir_columna(datos)
datos |
data.frame con columnas x, y, width, height, text (de pdf_data()) |
String con el texto de la columna en orden de lectura correcto
Levanta la aplicación Shiny y la abre en el navegador. Todas las consultas
salen desde la máquina donde se ejecuta, que es lo que permite llegar al
sitio del Parlamento: parlamento.gub.uy responde 403 a las IP de fuera de
Uruguay, así que la app necesita correr desde una conexión uruguaya.
abrir_app(puerto = NULL, navegador = TRUE)abrir_app(puerto = NULL, navegador = TRUE)
puerto |
Puerto donde levantar la app. Por defecto Shiny elige uno libre. |
navegador |
Si es |
Se invoca por su efecto: corre la app hasta que se la interrumpe.
if (interactive()) { abrir_app() }if (interactive()) { abrir_app() }
Analiza PDFs buscando un término principal y co-ocurrencias opcionales
analizar_pdfs( directorio, termino_principal, terminos_cruce = list(), progreso_fn = NULL )analizar_pdfs( directorio, termino_principal, terminos_cruce = list(), progreso_fn = NULL )
directorio |
Carpeta con los PDFs a analizar. También acepta la
ruta de un archivo |
termino_principal |
Expresión regular del término principal |
terminos_cruce |
Lista nombrada: list(turismo = "turist|extranjer") |
progreso_fn |
function(valor, mensaje) para reportar progreso |
tibble con columnas: archivo, ruta, legislatura, fecha, id_doc,
paginas_con_termino, cruce_[nombre], total_cruces, puntuacion,
fragmentos_texto, estado
Busca sesiones parlamentarias que mencionan un término dado
buscar_sesiones(texto, camara = "All", lgl_ids = c(49, 50), progreso_fn = NULL)buscar_sesiones(texto, camara = "All", lgl_ids = c(49, 50), progreso_fn = NULL)
texto |
Término a buscar (ej: "CANNABIS", "VIVIENDA SOCIAL") |
camara |
Cámara: "All" (ambas), "S" (Senado), "R" (Representantes) |
lgl_ids |
Vector de IDs de legislatura a buscar (ver LEGISLATURAS en global.R) |
progreso_fn |
Función opcional para reportar progreso: function(valor, mensaje) |
tibble con columnas: legislatura, lgl_id, cuerpo, fecha, id_doc, url_intermedia. Lleva siempre el atributo "errores": vector de mensajes con los fallos de red/HTTP que hubo. Un tibble vacío CON errores significa "no se pudo consultar el sitio"; vacío SIN errores, "el sitio no devolvió nada".
Usa nombres de archivo relativos para garantizar que el ZIP se pueda abrir correctamente en cualquier sistema operativo.
crear_zip(directorio, destino)crear_zip(directorio, destino)
directorio |
Carpeta con los PDFs a empaquetar |
destino |
Ruta del archivo ZIP de salida |
TRUE si el ZIP se creó correctamente, FALSE si no había PDFs
Cada PDF se nombra con el patrón: Lgl_[LEGISLATURA]_[FECHA]_ID_[ID].pdf
Si el archivo ya existe, lo omite sin re-descargarlo.
descargar_sesiones(sesiones, directorio, progreso_fn = NULL)descargar_sesiones(sesiones, directorio, progreso_fn = NULL)
sesiones |
tibble con columnas: legislatura, fecha, id_doc, url_intermedia |
directorio |
Carpeta destino (se crea si no existe) |
progreso_fn |
Función opcional: function(valor, mensaje) para reportar progreso |
tibble con columnas: archivo, estado (resultado por cada PDF)
Convierte score_raw a estrellas visuales (★★★☆☆)
estrellas_html(score_raw, max_stars = 5L)estrellas_html(score_raw, max_stars = 5L)
score_raw |
Vector numérico de scores crudos |
max_stars |
Número máximo de estrellas (default 5) |
Vector de strings HTML con estrellas
Gráfico de co-ocurrencias entre el término principal y términos secundarios
grafico_coocurrencias(datos, terminos_cruce)grafico_coocurrencias(datos, terminos_cruce)
datos |
tibble resultado de analizar_pdfs() |
terminos_cruce |
lista nombrada usada en el análisis |
objeto plotly o NULL si no hay términos de cruce
Gráfico interactivo de menciones a lo largo del tiempo
grafico_timeline(datos, titulo = "Menciones del término en el tiempo")grafico_timeline(datos, titulo = "Menciones del término en el tiempo")
datos |
tibble resultado de analizar_pdfs() |
titulo |
Título del gráfico |
objeto plotly
Tabla con las legislaturas que se pueden consultar, con el rango de fechas que el buscador oficial espera para cada una.
LEGISLATURASLEGISLATURAS
Un tibble con una fila por legislatura y las columnas etiqueta,
lgl_id, fecha_desde y fecha_hasta.
Los diarios de sesión están disponibles en línea a partir del 15/02/1985 (inicio de la XLII, restauración democrática). Las legislaturas XL y XLI son previas al golpe de Estado de 1973: pueden tener documentos limitados o ninguno según el cuerpo que se busque.
Usa httr con User-Agent de navegador real. Prueba tres selectores CSS en cascada para cubrir tanto la estructura actual del sitio como páginas antiguas de legislaturas anteriores (que usan HTML diferente).
obtener_url_pdf(url_intermedia)obtener_url_pdf(url_intermedia)
url_intermedia |
URL del visor de documentos del parlamento |
URL del PDF como string, o NA si no se encuentra