Descargando datos Web con R y Wget

Tiempo estimado de lectura < 4 min

En esta publicación traigo algo que ya hice hace casi un año, pero en lo que he perdido la práctica. Bueno, realmente aquella vez utilicé Wget para la recopilación de archivos de Internet y SAS para el tratamiento de los archivos.

Con R, a diferencia de SAS, es muy fácil el acceso a los archivos online. Si programas en R de manera habitual, sabrás que hay muchas funciones para la lectura de archivos, ya estén éstos en el ordenador o en Internet. Lo de hoy va de descargarse un montón de archivos HTML de un sitio protegido contra autómatas, extraer información de esos HTML y organizarla.

Para R existen algunos paquetes que permiten efectuar peticiones HTTP y FTP, para la emisión y recepción de información a un servidor. Rcurl, por ejemplo, es uno de ellos. Reconozco haber utilizado la herramienta curl en el pasado, pero mi falta de pericia no me ha permitido utilizar Rcurl con éxito… (lo reconozco, me escupía algún error y después de un minuto pensé en otra alternativa…)

Como decía, apunté hacia curl al empezar a trabajar en este mini-proyecto, pero pronto me acordé de algo: Wget. Wget es una herramienta INCREÍBLE y súper POTENTE para recopilar cualquier cosa de la Web. Con apenas 3 ó 4 opciones y una URL objetivo, podemos hacer una descarga a medida. Esto es, por ejemplo, ‘descárgame esta imagen, almacénala en este directorio con este nombre, reintenta la petición 5 veces en caso de fallo, y mantén la conexión abierta para la siguiente petición”. Por ejemplo. En la documentación se pueden encontrar todas las opciones.

Así que al final terminé llamando a Wget desde R a través de la función nativa de R, ‘system’, a la par que manipulaba dicha llamada para que hiciese petición por petición. (Nota: Wget también cuenta con parámetros para lanzar una lista de peticiones http sencillamente).

Para ello utilicé la siguiente función, a la que llamo desde un mapply (mapply recorre listas/vectores paralelamente):

[code language=”r”]
f.DescargaFichero <- function (unId, unUrl, unaEspera) {
Sys.sleep(unaEspera);
return(system(command = paste0("\"C:/Program Files (x86)/GnuWin32/bin/wget.exe\" –user-agent=\"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36\" –no-check-certificate –output-document=\"", getwd(), "/descargas/archivo", str_pad(string = as.character(unId), width = 4, side = "left", pad = "0"), ".html\" ", unUrl)));
}

basura <- mapply(FUN = f.DescargaFichero, VECTOR_IDs, VECTOR_URLs, VECTOR_ALEATORIOS);
[/code]

A la función le llegan 3 valores:

  • unID: es un número para identificar el archivo. Podría haber sido una simple cadena de texto, también.
  • unURL: la dirección http que queremos descargar.
  • unaEspera: un número de segundos a esperar antes de ejecutar la petición. (De esta manera hay menos probabilidad de que el servidor nos cierre la conexión porque se piense que estamos sobresaturándole con peticiones).

En sí, la función primero espera una cantidad de segundos, y después devuelve el valor del resultado de la función system, pero no es éste resultado el que nos interesa, sino que wget haga su trabajo: descargar el documento HTML.

A la función system se le pasa una cadena de texto, que es la orden que queremos ejecutar en nuestro sistema. Ésta cadena se compone de dos partes:

  1. La llamada a wget: \”C:/Program Files (x86)/GnuWin32/bin/wget.exe\” (se debe utilizar la barra invertida para las dobles comillas dentro de la cadena de texto…)
  2. Los parámetros de wget y los valores (algunos de estos valores cambian según lo que le demos a la función f.DescargaFichero): –user-agent=\”Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36\” –no-check-certificate –output-document=\””, getwd(), “/descargas/archivo”, str_pad(string = as.character(unId), width = 4, side = “left”, pad = “0”), “.html\” “, unUrl. Separando, nos encontramos con:
    • –user-agent=\”Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36\”, que básicamente “disfraza” a wget como un navegador. En este caso, dado que utilicé el navegador Maxthon, se mencionan varios motores de renderización, como Mozilla o Safari. Se puede conocer el user-agent de un navegador aquí, por ejemplo.
    • –no-check-certificate, para no comprobar el certificado de seguridad del sitio.
    • –output-document=\””, getwd(), “/descargas/archivo”, str_pad(string = as.character(unId), width = 4, side = “left”, pad = “0”), “.html\”, para decir el nombre del archivo de salida y dónde lo vamos a almacenar. Aquí, además, utilizo la función nativa de R getwd() y la variable unID.
    • unUrl, la dirección web del archivo que queremos descargar.
Archivos HTML descargados.
Archivos HTML descargados y listos para ser procesados..

Finalmente, una vez se habían descargado todos los documentos HTML, me dispuse a extraer los textos de estos (desde el propio R).

Wget es una herramienta que nos da la posibilidad de descargar información desestructurada de Internet, ya sea con fines analíticos, organizativos o simplemente para recolectar conocimiento.

¡Ciao!

Descargando datos Web con R y Wget

Leave a Reply

Your email address will not be published. Required fields are marked *