Objetivos del taller

Que vamos a hacer?

Reunimos: Fuentes de datos

Y en el foro discutimos:

Transparencia MUNISC

El proyecto del grupo se va a llamar “ActasTransparentes” para dar acceso a análisis de minería de texto a las actas de la municipalidad. Esta en Github:

https://github.com/SanCarlos-RUG/ActasTransparentes

Trabajar con datos de la red

  • Bajar documentos PDF desde una pagina en linea
    • Automatizar el indice de los archivos
    • Bajar solo los PDF
    • Traducir los PDF a texto

Un ensayo primero

Antes de bajar todos los archivos de la pagina de la municipalidad, hagamos un ensayo con Github.

  • 91 archivos …
  • En total 495.5 MB
  • No queremos sobrecargar el sitio de la municipalidad
  • No queremos hacerlo a mano

Un ejemplo con Github

En R tenemos algo similar a wget para bajar archivos:

Pero ninguna de las dos nos da tantas posibilidades como el paquete rvest.

Leer HTML

Obtén todos los eslabones de la pagina:

https://training.github.com/kit/

# Cargamos la biblioteca rvest
library(rvest)

pagina_completa <- read_html("https://training.github.com/kit/")

eslabones <- pagina_completa %>% 
  html_nodes("a") %>% 
  html_attr("href") 

Para genera la lista limpia de documentos pdf usamos el tipo de documento como indicado en el nombre del archivo.

eslabones_pdf <- unique(eslabones[grepl(".*.pdf.*", eslabones)])

Ahora los podemos bajar los archivos.

Empezamos con el primero:

eslabones_pdf[1]

# set the URL as a variable:
url <- "https://training.github.com/kit/"
file <- eslabones_pdf[1]

download.file(url, eslabones_pdf[1], mode="wb")

Veras que esto da un error. Según R no puede crear el archivo downloads/github-git-cheat-sheet.pdf.

> download.file(url, eslabones_pdf[1], mode="wb")
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
Warning: Failed to create the file downloads/github-git-cheat-sheet.pdf: No 
Warning: such file or directory
100  8595  100  8595    0     0  17143      0 --:--:-- --:--:-- --:--:-- 17155
curl: (23) Failed writing body (0 != 8595)
Warning message:
In download.file(url, eslabones_pdf[1], mode = "wb") :
  download had nonzero exit status

La razón es porque el nombre del archivo que estamos bajando contiene una referencia a la carpeta “downloads”. Lo podríamos remover, y añadir al URL. Pero aun mas facón es simplemente crear la carpeta “download” en nuestra carpeta de trabajo (working directory).

Ahora nos aseguramos de poder todos los nombres de los archivos:

for (file in eslabones_pdf) {
  print(file)
}

Y los bajamos todos

for (file in eslabones_pdf) {
   download.file(url, file, mode="wb")
}

Ehhhhh, quizas no todos … Ahora nos siguen faltando carpetas.

Cuales??

Separemos los eslabones en componentes:

strsplit(file, split="/")
download_components <- strsplit(file, split="/")[[1]]
for (current_url in eslabones_pdf) {
     download_components <- strsplit(current_url, split="/")[[1]]
     dc_length <- length(download_components)
     
     file <- download_components[max(dc_length)]
     for (i in 1:(max(dc_length)-1)){
       #current_url <- paste(url, "/", download_components[i], sep="")
      # current_url <- paste(url, "/", download_components[i], file, sep="")
     }
     cat("url: ", current_url, "file:", file, "\n")
     download.file(paste(url, current_url, sep=""),
                   file, mode="wb")
}

Pero, pero, solo hay un archivo! (porque?)

Solucion 1

library(uuid)
url <- "https://training.github.com/kit/"
file <- "download.pdf"
for (current_url in eslabones_pdf) {
   uuid <- strsplit(UUIDgenerate(), split = "-")[[1]][1]
   download.file(url=paste(url, current_url, sep=""), 
                 destfile=paste("downloads/", uuid, "-", file, sep = ""), 
                 mode="wb")
     cat("url: ", paste(url, current_url, sep=""), 
         "file:", paste(uuid, file, sep="-"),
                        "\n")
}

Solución 2

url <- "https://training.github.com/kit/"
for (current_url in eslabones_pdf) {
     download_components <- strsplit(current_url, split = "/")[[1]]
     dc_length <- length(download_components)
     
     if (dc_length == 2) {
       file <- download_components[2]
       cat("url: ", current_url, "file:", file, "\n")
       download.file(url = paste(url, current_url, sep=""), 
                     destfile = file, 
                     mode = "wb")
     } else { 
       file <- download_components[max(dc_length)]
     cat("url: ", current_url, "file:", file, "\n")
       download.file(url = paste(url, current_url, sep = ""), 
                   destfile = paste(download_components[2], "-", file, sep=""), 
                   mode = "wb")
     }
}

Porque la solución 2 es horrible (y nunca debe poner en produccion?)

Otras soluciones

# Otras soluciones?
# Hay muchas, presenta la tuya en el taller.

Ahora un wordcloud

library(wordcloud)
## Loading required package: RColorBrewer
library(tm)
## Loading required package: NLP
cheat_sheet <- readPDF(control = list(text = 
                   "-layout"))(elem = list(
                     uri = "es-github-git-cheat-sheet.pdf"),
                                language = "en",
                                id = "id1")

Sobre readPDF()

  • Porque se ve tan difícil (analiza la función y los argumentos)
  • Cuales alternativas para readPDF hay?

Ahora si un wordcloud

cheat_sheet <- Corpus(VectorSource(cheat_sheet$content))
cheat_sheet <- tm_map(cheat_sheet, content_transformer(tolower))
cheat_sheet <- tm_map(cheat_sheet, removePunctuation)
cheat_sheet <- tm_map(cheat_sheet, PlainTextDocument)
cheat_sheet <- tm_map(cheat_sheet, removeWords, stopwords('spanish'))

cheat_sheet <- tm_map(cheat_sheet, stemDocument)
wordcloud(cheat_sheet, max.words = 100, random.order=FALSE)

Actas del municipio

Usar un archivo como ejemplo

  • Baja uno archivo del municipio para tratar
  • Construye un wordcloud desde el archivo

Archivos municipalidad:

Atención: No corras el siguiente código a menos que quieras bajar todos los 590 MB de archivos.

transp_munisc <- read_html("http://www.munisc.go.cr/Paginas/Visitantes/Transparencia.aspx")

eslabones_transp <- transp_munisc %>% 
  html_nodes("a") %>% 
  html_attr("href") 

eslabones_actas <- unique(eslabones_transp[grepl(".*.pdf.*", eslabones_transp)])

url <- "http://www.munisc.go.cr/Paginas/Visitantes/"
file <- "actas.pdf"
for (current_url in eslabones_actas) {
   uuid <- strsplit(UUIDgenerate(), split = "-")[[1]][1]
   download.file(url=paste(url, current_url, sep=""), 
                 destfile=paste("downloads/", uuid, "-", file, sep = ""), 
                 mode="wb")
     cat("url: ", paste(url, current_url, sep=""), 
         "file:", paste(uuid, file, sep="-"),
                        "\n")
}

Ensayo con un solo acta

library(wordcloud)
library(tm)

acta <- readPDF(engine="xpdf", control = list(text = 
              "-layout"))(elem = list(
                uri = "data/5b340655-actas.pdf"),
                           language = "en",
                           id = "id1")

jpeg8.dll

Si encuentras un error sobre jpeg8.dll baja los binarios precompilados de Xpdf:

http://www.foolabs.com/xpdf/download.html

y pon los archivos pdfinfo.exe y pdftotext.exe en tu carpeta de trabajo (working directory).

Ahora un actacloud

acta <- Corpus(VectorSource(acta$content))
acta <- tm_map(acta, content_transformer(tolower))
acta <- tm_map(acta, removePunctuation)
acta <- tm_map(acta, PlainTextDocument)
acta <- tm_map(acta, removeWords, stopwords('spanish'))

wordcloud(acta, max.words = 1000, random.order=FALSE)

Stemming

acta_stemmed <- tm_map(acta, stemDocument)

wordcloud(acta_stemmed, max.words = 1000, random.order=FALSE)

Remueve palabras

acta_filtered <- tm_map(acta_stemmed, removeWords, c("municip", "concejo", "carlo",
                                             "san", "2015", "ordinaria",
                                             "febrero", "sesion"))
acta_filtered <- tm_map(acta_filtered, stemDocument)
wordcloud(acta_filtered, max.words = 1000, random.order=FALSE)