Curso

Web Scraping con R y RStudio

Una introducción

Dr. Agustín Nieto (INHUS-CONICET/UNMdP)

24 de junio de 2025

Centro de Estudios Andaluces

¿Qué es una página estática?

En esencia, una página web es solo un archivo HTML que se muestra en un navegador web. Cuando visita un sitio web, su navegador envía una solicitud al servidor web que aloja el sitio y el servidor responde devolviendo un archivo HTML junto con algunos otros archivos relacionados. Su navegador procesa este archivo HTML y se lo muestra como una página. En última instancia, tanto los sitios web estáticos como los dinámicos generan archivos HTML, pero lo que hace que un sitio web sea estático versus dinámico depende de cómo el servidor crea este archivo HTML antes de enviárselo.

Una página web estática es una página web que se entrega al navegador del usuario exactamente como está almacenada, en contraste con las páginas web dinámicas que son generadas por una aplicación web. En consecuencia, una página web estática muestra la misma información para todos lxs usuarixs. Las páginas web estáticas suelen ser documentos HTML almacenados como archivos en el sistema de archivos y puestos a disposición por el servidor web a través de HTTP. Sin embargo, las interpretaciones laxas del término podrían incluir páginas web almacenadas en una base de datos, e incluso podrían incluir páginas formateadas utilizando una plantilla y servidas a través de un servidor de aplicaciones, siempre que la página servida no cambie y se presente esencialmente como almacenada.

Introducción al paquete {rvest}

El paquete rvest nos ayuda a extraer y recolectar datos de páginas web estáticas y dinámicas (estas últimas con la ayuda de RSelenium). Está diseñado facilitar las tareas comunes de raspado web. rvest está inspirado en paquetes como beautiful soup y RoboBrowser de Python.

Si vamos a ‘raspar’ varias páginas web, es recomendable utilizar, junto a rvest, el paquete polite. El paquete polite asegura que se respeten los términos del documento robots.txt y que nuestras solicitudes no sobrecarguen el sitio web que estamos ‘raspando’. El archivo robots.txt indica a los rastreadores de los buscadores qué páginas o archivos del sitio se pueden solicitar y cuáles no. Como ya dijimos, se utiliza para evitar que las solicitudes que recibe el sitio lo sobrecarguen.

El paquete rvest es parte de tidyverse, un ecosistema de paquetes diseñados con APIs comunes y una filosofía compartida. Para más información véase tidyverse.org.

Más info sobre el paquete rvest

Función para leer documentos HTML

La función read_html() es originaria del paquete xml2 que trabaja con archivos XML y usa una interfaz simple y consistente. El paquete xml2 fue diseñado en base al paquete libxml2 del lenguaje C. La función read_html() convierte un documento XML/HTML (o nodo o conjunto de nodos) en una lista R equivalente.

Más info sobre la función read_html()

Función para extraer nodos

Las funciones html_element() y html_elements() permiten extraer con facilidad fragmentos de documentos HTML mediante los selectores XPath y CSS.

Argumentos

x

Un documento, un conjunto de nodos o un solo nodo.

css, xpath

Nodos para seleccionar. Proporcione uno de css o xpath dependiendo de si desea utilizar un selector CSS o XPath 1.0.

Más info sobre la función html_elements()

Función para extraer texto

Hay dos formas de recuperar texto de un elemento html: html_text() y html_text2(). La función html_text() es una fina envoltura alrededor de la función xml2::xml_text() que devuelve solo el texto subyacente sin procesar. Por su parte, html_text2() simula cómo se ve el texto en un navegador y utiliza un enfoque inspirado en la función innerText() de JavaScript. En términos generales, convierte la etiqueta <br /> en \n, agrega líneas en blanco alrededor de las etiquetas <p> y formatea ligeramente los datos tabulares.

Vale aclarar que html_text2() suele devolver lo que se desea en la forma en que se desea, pero es mucho más lento que html_text(). Por esta razón es recomendable usar html_text() para raspados de mayor volumen.

Más info sobre la función html_text()

Función para extraer atributos de elementos HTML

html_attr() obtiene un solo atributo; html_attrs() obtiene todos los atributos.

library(rvest)
minimal_html('<ul><li><a href="https://a.com" class="important">a</a></li></ul>') |> 
  html_elements("a") |> html_attr("href")
## [1] "https://a.com"

Más info sobre la función html_attr()

Función para extraer tablas

La función html_table transforma una tabla html en un marco de datos.

library(rvest)
minimal_html("<table><tr><th>Col A</th><th>Col B</th></tr>
  <tr><td>1</td><td>x</td></tr><tr><td>4</td><td>y</td></tr>
  <tr><td>10</td><td>z</td></tr></table>") |> 
  html_element("table") |> html_table()
## # A tibble: 3 × 2
##   `Col A` `Col B`
##     <int> <chr>  
## 1       1 x      
## 2       4 y      
## 3      10 z

Más info sobre la función html_table()

Otro paquete para Web Scraping: {Rcrawler}

{Rcrawler} es un paquete R para rastrear sitios web y extraer datos estructurados que se pueden usar para una amplia gama de aplicaciones útiles, como minería web, minería de texto, minería de contenido web y minería de estructuras web. Entonces, ¿cuál es la diferencia entre Rcrawler y rvest?: rvest extrae datos de una página específica navegando a través de selectores. Rcrawler atraviesa y analiza automáticamente todas las páginas web de un sitio web y extrae todos los datos que necesita de ellos a la vez con un solo comando..

Más info sobre el paquete {Rcrawler}

¿Cómo realizar un raspado masivo de un sitio estático?

La clave para raspar de forma masiva el contenido específico de un sitio con páginas estáticas es la construcción de un listado (vector) de urls desde distintas páginas estáticas.

Una vez que logramos armar el listado podemos recorrer cada una de las páginas para extraer el contenido deseado.

El recorrido página por página lo podemos automatizar con un ciclo for. Pero antes de ver qué es un ciclo for recordemos qué es una url.

Qué es un url

URL significa (en castellano) Localizador de Recursos Uniforme. En concreto, los URLs son cadenas de caracteres con las que se asigna una dirección única a cada uno de los recursos de información disponibles en Internet. Existe un único URL para cada recurso de Internet. El URL de un recurso es su dirección en Internet, la cual permite que el navegador la encuentre. El formato general de un URL es: :esquema://máquina/directorio/archivo

Más info sobre los URLs

Introducción al ciclo for

El ciclo for es uno de los más utilizados en programación debido a que permite repetir varias instrucciones un cierto número de ocasiones (por ejemplo, 5 veces). Se emplea en el recorrido de vectores y otras estructuras de datos.

Características:

  • Siempre se hace uso de una variable (contador) que incrementará su valor automáticamente y ayudará a determinar si se continúa o finaliza el ciclo.
  • El contador deberá inicializarse con un valor, generalmente 0 o 1.
  • Un ciclo puede contener otro ciclo dentro de sí (a esto se le denomina ciclo anidado).

Más info sobre el ciclo for

{purrr} un paquete de funciones para iterar

El paquete {purrr} mejora el conjunto de herramientas de programación funcional de R al proporcionar un conjunto completo y consistente de herramientas para trabajar con funciones y vectores. Este paquete tiene funciones que le permiten reemplazar muchos bucles for con código más breve y más fácil de leer.

Más info sobre la función html_text()

La función map_df()

Las funciones map transforman su entrada aplicando una función a cada elemento de una lista o vector atómico y devolviendo un objeto de la misma longitud que la entrada.

library(purrr)
map_vec(1:9, sqrt)
## [1] 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490 2.645751 2.828427
## [9] 3.000000

Más info sobre las funciones map

Colecciones de urls

Un truco para crear listas con miles de urls consiste en descubrir la estructura url de las páginas individuales. Un ejemplo son las páginas de periódicos y sus páginas de notas individuales: https://www.lacapitalmdp.com/notas-al-pie-de-la-pandemia-sin-perder-la-ternura-jamas/4656/

urls <- paste0("https://www.lacapitalmdp.com/notas/", 1999:4999)
head(urls)
## [1] "https://www.lacapitalmdp.com/notas/1999"
## [2] "https://www.lacapitalmdp.com/notas/2000"
## [3] "https://www.lacapitalmdp.com/notas/2001"
## [4] "https://www.lacapitalmdp.com/notas/2002"
## [5] "https://www.lacapitalmdp.com/notas/2003"
## [6] "https://www.lacapitalmdp.com/notas/2004"

{httr} un paquete complementario para {rvest}

Este paquete contiene herramientas útiles para trabajar con HTTP organizado por verbos HTTP (GET(), POST(), etc). Las funciones de configuración facilitan el control de componentes de solicitud adicionales.

Más info sobre las funciones de la librería {httr}