Volver al blog
Guías
Raluca PenciucLast updated on Mar 31, 20269 min read

Cómo el web scraping en R hace que la ciencia de datos sea divertida

Cómo el web scraping en R hace que la ciencia de datos sea divertida

A medida que evoluciona la web, se generan más datos de forma dinámica. Esto hace que sea más difícil extraerlos mediante una API. El web scraping en R viene al rescate de los científicos de datos, cuyos proyectos requieren enormes cantidades de datos.

Afortunadamente, los lenguajes de programación también han evolucionado para hacer frente a estas situaciones. Un ejemplo popular de este tipo de lenguaje es R, diseñado para gestionar mejor tareas de gran volumen.

En este tutorial, repasaré los principios básicos hablando de la utilidad de R en la vida real. También describiré uno de los paquetes más populares utilizados en el web scraping con R, rvest. A continuación, ilustraré cómo funciona R a la hora de extraer los datos de un sitio web.

Introducción a R

R es la versión de código abierto del lenguaje de programación S, combinada con la semántica de Scheme. Apareció por primera vez a mediados de 1993, se convirtió en código abierto en 1995 y tuvo su primera versión beta estable en 2000.

Ross Ihaka y Robert Gentleman diseñaron R con el propósito de «convertir ideas en software de forma rápida y fiel».

R es un lenguaje de programación funcional y es muy conocido entre los científicos de datos. Sus casos de uso más populares son:

  • la banca;
  • finanzas;
  • comercio electrónico;
  • aprendizaje automático;
  • cualquier otro sector que utilice grandes cantidades de datos.

En comparación con SAS y SPSS, R es la herramienta de análisis más utilizada del mundo. Su comunidad, activa y solidaria, cuenta con casi 2 millones de usuarios.

Si echamos un vistazo a algunas de las empresas que integran R en sus negocios y cómo lo hacen, veríamos:

  • Facebook: para actualizar el estado y su grafo de red social;
  • Google: para predecir la actividad económica y mejorar la eficiencia de la publicidad online;
  • Foursquare: para su motor de recomendaciones;
  • Trulia: para predecir los precios de la vivienda y las tasas de criminalidad locales.

Sin embargo, en comparación con otros lenguajes, R compite constantemente con Python. Ambos ofrecen herramientas de web scraping y cuentan con comunidades activas.

Las diferencias se hacen evidentes cuando nos fijamos en el público objetivo. Python tiene una sintaxis muy fácil de aprender y muchas funciones de alto nivel. Esto lo hace más atractivo para principiantes y usuarios sin conocimientos técnicos.

R puede parecer un poco intimidante al principio, pero está más enfocado al análisis estadístico. Ofrece un conjunto más amplio de herramientas integradas de análisis y visualización de datos. Por lo tanto, puede ser una mejor opción para proyectos en los que se manejan grandes cantidades de datos, como el web scraping.

Acerca de rvest

Rvest es uno de los paquetes más populares utilizados para el web scraping en R. Ofrece funciones de análisis sintáctico potentes, pero sencillas. BeautifulSoup de Python sirve como fuente de inspiración y forma parte de la colección tidyverse.

Genial, pero ¿por qué usar rvest si R tiene bibliotecas nativas que hacen el mismo trabajo? La primera buena razón es que rvest es una envoltura de los paquetes httr y xml2. Esto significa que se encarga tanto de la solicitud GET como del análisis sintáctico del HTML.

De este modo, utilizas una sola biblioteca en lugar de dos y tu código será mucho más limpio y conciso. Además, rvest también puede recibir una cadena como entrada y encargarse del análisis de XML y de la descarga de archivos.

Sin embargo, debemos tener en cuenta que los sitios web tienen cada vez más contenido generado dinámicamente. Las razones son diversas: rendimiento, experiencia del usuario y muchas otras. Rvest no puede gestionar la ejecución de JavaScript, por lo que aquí es donde deberías buscar una alternativa.

Scraping con R

Bueno, basta de teoría. Veamos cómo se comporta R en un caso de uso real. Para este tutorial, he elegido la página de Goodreads de un libro muy famoso: 1984, de George Orwell. Puedes encontrar el sitio web aquí: https://www.goodreads.com/book/show/61439040-1984.

Quiero ver cómo ha evolucionado la popularidad de este libro a lo largo de los años. Para estimarlo, voy a extraer la lista de reseñas y extraer la fecha y la valoración de cada reseña. Como paso final, guardaré los datos en un archivo externo que luego puedan procesar otros programas.

Configurar el entorno

Pero primero, debes asegurarte de que tienes todo lo necesario para escribir el código.

En cuanto al IDE, tienes dos opciones:

  • instalar un complemento de R para Visual Studio Code;
  • descargar RStudio, diseñado para facilitar la programación en R.

En este tutorial, utilizaré esta última opción. Puedes descargarlo aquí: https://www.rstudio.com/products/rstudio/download/.

La versión gratuita de RStudio Desktop es suficiente para que te familiarices con los conceptos básicos. Como antes, sigue las instrucciones de instalación.

Abre RStudio y crea un nuevo directorio vacío. Escribiré el código en un nuevo archivo llamado «goodreads-rvest.r».

Presentación del navegador

Ahora, antes de extraer los datos, debes saber qué datos quieres. Rvest maneja tanto selectores CSS como XPath, así que elige tu opción. 

Si tienes pensado iniciar proyectos de scraping más complejos, te recomiendo tener conocimientos básicos de HTML y CSS. Aquí tienes un buen sitio para empezar.

Si no estás familiarizado con todo el tema del HTML, también hay algunas opciones no técnicas. Por ejemplo, Chrome ofrece la extensión de navegador SelectorGadget. Te permite hacer clic en cualquier lugar de la página y te muestra el selector CSS para obtener los datos.

Sin embargo, no todos los sitios web son tan sencillos como Goodreads. Yo optaré por recuperar los datos utilizando selectores CSS que encontraré inspeccionando manualmente el HTML.

Ve a nuestra URL de destino en tu navegador y desplázate hacia abajo hasta la sección «Reseñas de la comunidad». A continuación, haz clic con el botón derecho del ratón y selecciona «Inspeccionar» para abrir las Herramientas de desarrollador.

El contenedor con el identificador «other_reviews» es en el que me centraré. Ahora utiliza el botón «Inspeccionar» para encontrar el selector CSS de la fecha y la valoración de una reseña.

Así, puedes observar lo siguiente:

  • cada reseña individual es un contenedor div con la clase «review»;
  • la fecha de la reseña es un único elemento de anclaje con la clase «reviewDate»;
  • la valoración de la reseña es un elemento span con la clase «staticStars». Tiene cinco elementos span como hijos, el número de estrellas que un usuario puede asignar. Nos fijaremos en los que están coloreados, que tienen la clase «p10».

Extracción de las reseñas

Después de comprobar todos los requisitos previos, por fin puedes empezar a escribir el código.

install.packages('rvest')

Coloca el cursor al final de la línea y pulsa el botón «Run» situado encima del editor de código. Verás en tu consola el progreso de la instalación del paquete.

La instalación se realiza una sola vez, por lo que ahora puedes comentar o eliminar la línea anterior:

#install.packages('rvest')

Ahora tienes que cargar (o importar) la biblioteca:

library(rvest)

Utilizaré la función read_html para enviar una solicitud GET al sitio web de destino, lo que descargará el documento HTML necesario. De esta forma, descargaré el documento HTML necesario:

book_html <- read_html("https://www.goodreads.com/book/show/61439040-1984")

El resultado se almacena ahora en la variable book_html, que también puedes ver simplemente escribiendo en la consola:

Si en algún momento necesitas consultar la documentación oficial de una función que quieras utilizar, escribe en la consola:

help(function_name) 

RStudio abrirá un servidor HTTP con un enlace directo a la documentación. Para read_html, el resultado será:

Para obtener la lista de reseñas, utilizaré la función html_elements. Recibirá como entrada el selector CSS que encontré anteriormente:

reviews <- book_html %>% html_elements('div.review')

El resultado será una lista de nodos XML, que recorreré para obtener la fecha y la valoración de cada elemento individual:

Los programadores de R utilizan el operador de barra vertical «%>%» para hacer la programación más versátil. Su función es pasar el valor del operando de la izquierda como argumento al operando de la derecha.

Puedes encadenar los operandos (como verás más adelante en esta guía), lo que te ayudará a reducir el uso de muchas variables locales. La línea de código anterior escrita sin el operador pipe quedaría así:

reviews <- html_elements(book_html, 'div.review')

Para recopilar los datos, inicializaré dos vectores fuera del bucle. Echando un vistazo rápido al sitio web, puedo garantizar que ambos vectores tendrán la misma longitud.

dates <- vector()
ratings <- vector()

Ahora, mientras recorro la lista de reseñas, busco dos valores: la fecha y la valoración. Como has visto antes, la fecha es un elemento anchor que tiene la clase reviewDate.

La valoración es un elemento span con la clase staticStars, y contiene cinco elementos span para cada estrella. Si el usuario ha otorgado una estrella, el elemento span tendrá el nombre de clase p10, mientras que el resto tendrá el nombre de clase p0.

El código tendrá este aspecto:

for (review in reviews) {
  review_date = review %>% html_element('a.reviewDate') %>% html_text()
  dates <- c(dates, review_date)
 
  review_rating_element = review %>% html_element('span.staticStars')
  valid_stars = review_rating_element %>% html_elements('span.p10')
  review_rating = length(valid_stars)
  ratings <- c(ratings, review_rating)
}

Fíjate en la función html_element; no es un error tipográfico. Puedes usar html_elements cuando quieras extraer una lista de nodos XML y html_element para uno solo.

En este caso, he aplicado esta última a una sección más pequeña del documento HTML (una reseña). También he utilizado la función html_text para obtener el contenido de texto del elemento que he encontrado. 

Por último, fusionaré los dos vectores en un único marco de datos para centralizar la información:

result = data.frame(date = dates, rating = ratings)

Y el resultado final tendrá este aspecto:

Guardar los resultados

Todos sabemos que el scraping no sirve de nada si no se guardan los resultados en algún sitio. En R, escribir en un CSV no es más que:

write.csv(result, "reviews.csv")

El resultado tiene que ser una matriz o un marco de datos (que ya lo es); de lo contrario, intentará una conversión. Ejecuta el código y comprueba el directorio del proyecto. Verás que puedes abrir la tabla anterior en un editor de texto, un documento de Excel, etc.

El resultado tiene que ser una matriz o un marco de datos (que ya lo es); de lo contrario, intentará realizar una conversión. Ejecuta el código y comprueba el directorio del proyecto. Verás que puedes abrir la tabla anterior en un editor de texto, un documento de Excel, etc.

Huelga decir que nuestra lista de datos solo tiene 30 entradas. El sitio web muestra más de 90 000 reseñas y más de 3 millones de valoraciones. ¿Qué ha pasado entonces? Pues la paginación.

Es más, vuelve a tu navegador y haz clic en la segunda página. Verás que la lista cambia, pero la URL no. Esto significa que utilizan un estado para cargar dinámicamente otra sección de la lista.

En estas situaciones, rvest puede no ser útil. En su lugar, un navegador automatizado puede ayudar a imitar el comportamiento de los clics para cargar el resto de la lista. Un ejemplo de una biblioteca de este tipo es RSelenium, pero dejaré este tema como ejercicio de seguimiento.

Conclusión

Espero que este tutorial te haya proporcionado una base sólida para el web scraping con R. Ahora podrás tomar una decisión más fácilmente sobre la pila tecnológica de tu próximo proyecto.

No obstante, ten en cuenta que este artículo no ha abordado los numerosos retos del web scraping. Puedes encontrarlos explicados con más detalle en esta guía autoexplicativa.

Acerca del autor
Raluca Penciuc, Desarrollador full-stack @ WebScrapingAPI
Raluca PenciucDesarrollador full-stack

Raluca Penciuc es desarrolladora full stack en WebScrapingAPI, donde se dedica a crear rastreadores, mejorar las técnicas de evasión y buscar formas fiables de reducir la detección en los sitios web de destino.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.