library(rvest)
library(magrittr)
En este primer chunk, cargamos las librerías rvest y magrittr.
rvest: permite realizar web scraping en R, ayudando a leer y extraer datos de páginas web. magrittr: facilita el uso de operadores como %>% para hacer código más legible y fácil de seguir.
crear_urls <- function(fecha_inicio, fecha_final) {
# Convertir las fechas de inicio y final a Date
fecha_inicio <- as.Date(fecha_inicio)
fecha_final <- as.Date(fecha_final)
# Crear secuencia de fechas entre fecha_inicio y fecha_final
fechas <- seq(fecha_inicio, fecha_final, by = "day")
# Aplicar la función generar_url a cada fecha
urls <- sapply(fechas, generar_url)
return(urls)
}
En este chunk, definimos la función crear_urls, la cual genera una lista de URLs para cada fecha en el rango especificado:
generar_url <- function(fecha) {
# Cambiar configuración regional a español
Sys.setlocale("LC_TIME", "es_ES.UTF-8")
# Formatear el día sin cero inicial
dia <- as.numeric(format(fecha, "%d"))
mes <- tolower(format(fecha, "%B"))
anio <- format(fecha, "%Y")
fecha_formato <- paste(dia, "de", mes, "de", anio, sep = "-")
# Crear la URL con la fecha formateada
paste0("https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-",
fecha_formato)
}
Aquí definimos la función generar_url, que se encarga de transformar una fecha en una URL específica:
# Generar URLs entre el 1 de octubre y el 31 de octubre de 2024
urls <- crear_urls("2024-10-01", "2024-10-31")
print(urls)
## [1] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-1-de-octubre-de-2024"
## [2] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-2-de-octubre-de-2024"
## [3] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-3-de-octubre-de-2024"
## [4] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-4-de-octubre-de-2024"
## [5] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-5-de-octubre-de-2024"
## [6] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-6-de-octubre-de-2024"
## [7] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-7-de-octubre-de-2024"
## [8] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-8-de-octubre-de-2024"
## [9] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-9-de-octubre-de-2024"
## [10] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-10-de-octubre-de-2024"
## [11] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-11-de-octubre-de-2024"
## [12] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-12-de-octubre-de-2024"
## [13] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-13-de-octubre-de-2024"
## [14] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-14-de-octubre-de-2024"
## [15] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-15-de-octubre-de-2024"
## [16] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-16-de-octubre-de-2024"
## [17] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-17-de-octubre-de-2024"
## [18] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-18-de-octubre-de-2024"
## [19] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-19-de-octubre-de-2024"
## [20] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-20-de-octubre-de-2024"
## [21] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-21-de-octubre-de-2024"
## [22] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-22-de-octubre-de-2024"
## [23] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-23-de-octubre-de-2024"
## [24] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-24-de-octubre-de-2024"
## [25] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-25-de-octubre-de-2024"
## [26] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-26-de-octubre-de-2024"
## [27] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-27-de-octubre-de-2024"
## [28] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-28-de-octubre-de-2024"
## [29] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-29-de-octubre-de-2024"
## [30] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-30-de-octubre-de-2024"
## [31] "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-de-la-presidenta-claudia-sheinbaum-pardo-del-31-de-octubre-de-2024"
En este último chunk, utilizamos la función crear_urls:
En este paso, definimos la función scrape_y_guarda que realiza el web scraping para extraer el contenido de cada conferencia desde las URLs generadas y guardarlo en un archivo de texto (.txt).
scrape_y_guarda <- function(url) {
# Extraer la fecha desde la URL
fecha <- sub(".*del-([0-9]+-de-[a-z]+-de-[0-9]+).*", "\\1", url)
# Intentar leer la página HTML
pagina <- tryCatch(read_html(url), error = function(e) NULL)
if (!is.null(pagina)) {
# Extraer el texto usando el selector adecuado (ajustar según el HTML específico)
texto <- pagina %>%
# html_nodes(".contenido-conferencia") %>% # <-- ajustar con el selector CSS adecuado
html_text()
# Verificar que el texto no contenga "Error 404" o "La ruta no existe"
if (!grepl("Sitio en mantenimiento", texto, ignore.case = TRUE)) {
# Guardar el texto en un archivo .txt
nombre_archivo <- paste0("conferencia_", gsub(" ", "_", fecha), ".txt")
writeLines(texto, nombre_archivo)
} else {
cat(paste("El contenido de la conferencia para la fecha", fecha, "no está disponible.\n"))
}
} else {
cat(paste("No se pudo acceder a la página para la fecha:", fecha, "\n"))
}
}
La línea fecha <- sub(“.del-([0-9]+-de-[a-z]+-de-[0-9]+).”, “\1”, url) extrae la fecha desde la URL usando una expresión regular. Esto permite crear el nombre del archivo con la fecha específica de cada conferencia.
pagina <- tryCatch(read_html(url), error = function(e) NULL) intenta leer el contenido de la página web. Si hay algún error (por ejemplo, la página no está disponible), la función devuelve NULL.
Si la página se lee correctamente, usamos texto <- pagina %>% html_text() para extraer el texto. Ajuste del Selector CSS: Aquí debes reemplazar html_nodes(“.contenido-conferencia”) con el selector CSS que corresponda al contenido de la conferencia en la página web.
La línea if (!grepl(“Sitio en mantenimiento”, texto, ignore.case = TRUE)) asegura que el contenido descargado no sea una página de error. Si el contenido está disponible, pasamos al siguiente paso.
Si el contenido es válido, se guarda en un archivo .txt usando writeLines(texto, nombre_archivo). El archivo se nombra en función de la fecha extraída de la URL.
Si la página está en mantenimiento o la URL no es accesible, se muestra un mensaje indicando que el contenido no está disponible.
Ahora que la función scrape_y_guarda está lista, podemos aplicarla a cada URL de la lista usando lapply para automatizar el proceso.
# Aplicar la función a cada URL en la lista
lapply(urls, scrape_y_guarda)
## El contenido de la conferencia para la fecha 1-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 2-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 5-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 6-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 12-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 13-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 19-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 20-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 27-de-octubre-de-2024 no está disponible.
## El contenido de la conferencia para la fecha 28-de-octubre-de-2024 no está disponible.
## [[1]]
## NULL
##
## [[2]]
## NULL
##
## [[3]]
## NULL
##
## [[4]]
## NULL
##
## [[5]]
## NULL
##
## [[6]]
## NULL
##
## [[7]]
## NULL
##
## [[8]]
## NULL
##
## [[9]]
## NULL
##
## [[10]]
## NULL
##
## [[11]]
## NULL
##
## [[12]]
## NULL
##
## [[13]]
## NULL
##
## [[14]]
## NULL
##
## [[15]]
## NULL
##
## [[16]]
## NULL
##
## [[17]]
## NULL
##
## [[18]]
## NULL
##
## [[19]]
## NULL
##
## [[20]]
## NULL
##
## [[21]]
## NULL
##
## [[22]]
## NULL
##
## [[23]]
## NULL
##
## [[24]]
## NULL
##
## [[25]]
## NULL
##
## [[26]]
## NULL
##
## [[27]]
## NULL
##
## [[28]]
## NULL
##
## [[29]]
## NULL
##
## [[30]]
## NULL
##
## [[31]]
## NULL
lapply(urls, scrape_y_guarda): Este código aplica la función scrape_y_guarda a cada elemento de la lista urls. Para cada URL, se ejecuta el proceso de extracción y guardado explicado anteriormente.
Una vez que todos los archivos .txt se han guardado, podemos cargarlos para realizar análisis adicionales.
# Cargar archivos descargados para análisis
archivos <- list.files(pattern = "*.txt")
list.files(pattern = “*.txt”): Esta línea lista todos los archivos .txt en el directorio de trabajo actual. La lista de archivos se guarda en archivos, que puede usarse para cualquier procesamiento o análisis posterior.
Cargar y Limpiar el Texto: En este paso, leeremos el contenido de cada archivo .txt generado previamente, lo limpiaremos y prepararemos para el análisis.
library(tm)
## Loading required package: NLP
# Función para leer y limpiar el contenido de los archivos
limpiar_texto <- function(archivo) {
texto <- readLines(archivo, warn = FALSE) # Leer el archivo
texto <- paste(texto, collapse = " ") # Combinar todas las líneas en un solo texto
# Convertir a minúsculas y limpiar el texto de URLs, etiquetas HTML, puntuación, y espacios extra
texto <- tolower(texto)
texto <- gsub("http\\S+|www\\.\\S+", "", texto) # Remover URLs
texto <- gsub("<.*?>", "", texto) # Remover etiquetas HTML
texto <- gsub("[[:punct:]]", "", texto) # Remover puntuación
texto <- gsub("\\d+", "", texto) # Remover números
texto <- gsub("\\s+", " ", texto) # Eliminar espacios extra
return(texto)
}
# Leer y limpiar el texto de cada archivo
archivos <- list.files(pattern = "*.txt") # Listar los archivos generados
textos_limpios <- lapply(archivos, limpiar_texto) # Aplicar la limpieza a cada archivo
# Crear un Corpus para el análisis de texto
corpus <- Corpus(VectorSource(textos_limpios))
dtm <- DocumentTermMatrix(corpus) # Crear matriz de términos
Definir limpiar_texto: Esta función lee el archivo y realiza varias operaciones de limpieza.
Aplicar Limpieza: lapply(archivos, limpiar_texto) aplica la función a cada archivo en archivos, generando una lista de textos limpios.
Crear Corpus y Matriz de Términos: Usamos Corpus y DocumentTermMatrix del paquete tm para crear un corpus y una matriz de términos que nos permitirá analizar las palabras más frecuentes.
Sumamos la frecuencia de cada término en el corpus para identificar las palabras más comunes.
# Calcular la frecuencia total de cada término
conteo_total <- colSums(as.matrix(dtm))
terminos_comunes <- sort(conteo_total, decreasing = TRUE)
# Visualizar los términos más frecuentes
print(head(terminos_comunes, 10)) # Muestra las 10 palabras más comunes
## que los las del para por con
## 9829 3361 2652 2494 2483 2397 2309
## una presidenta también
## 2081 1836 1232
Usamos el paquete wordcloud para visualizar las palabras más frecuentes en una nube de palabras.
library(wordcloud)
## Loading required package: RColorBrewer
library(wordcloud2)
# Crear la nube de palabras
wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 50, max.words = 100, random.order = FALSE)
Como podemos ver nuestra nube tiene muchas palabras que son demasiado comunes y generan ruido en nuestro análisis. Estas palabras incluyen artículos, preposiciones y pronombres, entre otros, que aparecen frecuentemente pero que no agregan mucho significado en el contexto del análisis. Eliminar stopwords es un paso común en el preprocesamiento de texto. Así que tenemos antes de generar nuestro dtm es conveniente eliminar este tipo de palabras.
# Eliminar stopwords de nuestro corpus
corpus2 <- tm_map(corpus, removeWords, stopwords("es")) # Usar "es" para stopwords en español
## Warning in tm_map.SimpleCorpus(corpus, removeWords, stopwords("es")):
## transformation drops documents
Ahora repitamos el análisis anteriormente realizado y comparemos nuestros términos y nube de palabras
#creamos el nuevo DTM
dtm2 <- DocumentTermMatrix(corpus2)
# Sumar las columnas para obtener el conteo total de cada término
conteo_total2 <- colSums(as.matrix(dtm2))
# Ordenar y mostrar los términos más comunes
terminos_comunes2 <- sort(conteo_total2, decreasing = TRUE)
head(terminos_comunes2, 50) # Mostrar los 50 términos más comunes
## presidenta claudia sheinbaum entonces pardo
## 1836 1110 1110 1077 1016
## var vamos méxico pues gobierno
## 945 884 870 740 589
## dimension poder ver bueno mil
## 525 516 504 464 464
## ser parte caso cómo ahora
## 444 440 435 434 423
## tema hacer nacional aquí pregunta
## 420 413 403 395 395
## mujeres todas importante gracias reforma
## 384 383 373 371 368
## function hoy seguridad judicial país
## 357 355 355 344 342
## decir ahí null días dos
## 340 338 336 335 329
## pueblo presidente van pagetype octubre
## 326 325 325 315 308
## además gagobtrackerset usted programa día
## 301 294 294 280 275
# Crear la nube de palabras
wordcloud(names(terminos_comunes2), terminos_comunes2, min.freq = 50, max.words = 100, random.order = FALSE)
Si hay palabras específicas que deseas eliminar de tu análisis, puedes crear una lista de estas palabras y usar removeWords para quitarlas del corpus, de manera similar a como eliminaste las stopwords. Este paso debería realizarse después de haber eliminado las stopwords y antes de crear la Document-Term Matrix (DTM).
# Eliminar palabras específicas
palabras_eliminar <- c("null", "pardo", "vamos", "pues", "var", "function", "pagetype", "entonces", "gtagset", "gaset", "importante", "pregunta", "además", "cómo", "van", "tema", "gracias", "días", "decir", "octubre", "gagobtrackerset", "interlocutor", "interlocutora", "organizationname", "estenográfica", "contentgroup", "presidenta", "claudia", "sheinbaum", "méxico", "gobierno")
corpus3 <- tm_map(corpus2, removeWords, palabras_eliminar)
## Warning in tm_map.SimpleCorpus(corpus2, removeWords, palabras_eliminar):
## transformation drops documents
# Crear la nueva DTM
dtm3 <- DocumentTermMatrix(corpus3)
# Sumar las columnas para obtener el conteo total de cada término
conteo_total3 <- colSums(as.matrix(dtm3))
# Ordenar y mostrar los términos más comunes
terminos_comunes3 <- sort(conteo_total3, decreasing = TRUE)
head(terminos_comunes3, 50) # Mostrar los 50 términos más comunes
## dimension poder ver bueno mil ser
## 525 516 504 464 464 444
## parte caso ahora hacer nacional aquí
## 440 435 423 413 403 395
## mujeres todas reforma hoy seguridad judicial
## 384 383 368 355 355 344
## país ahí dos pueblo presidente usted
## 342 338 329 326 325 294
## programa día ayer general constitución secretaría
## 280 275 271 271 267 267
## manera salud años información hace personas
## 260 260 257 256 253 251
## unidos así después ley muchas conferencia
## 250 248 246 238 237 230
## prensa dice lópez ciento tener buenos
## 229 228 228 226 226 223
## bienestar obrador
## 218 216
# Convertir los términos y sus frecuencias a un data frame
terminos_df3 <- data.frame(
word = names(terminos_comunes3),
freq = as.numeric(terminos_comunes3)
)
# Crear la nube de palabras con wordcloud2
wordcloud2(terminos_df3, size = 0.5, color = "random-light", backgroundColor = "black")