Curso

Web Scraping con R y RStudio

Una introducción (parte 2)

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

26 de junio de 2025

Centro de Estudios Andaluces

¿Qué es una página dinámica?

Las páginas web dinámicas basan su comportamiento y funcionalidad en dos tipos de programación: front-end y back-end. JavaScript es el lenguaje de programación que se usa para las instrucciones del lado del cliente. Estas instrucciones se ejecutan en el navegador. Mientras que las instrucciones que se ejecutan del lado del servidor son instrucciones escritas en lenguajes de programación como PHP y que son ejecutadas para crear lo que se ha solicitado en interacción con la página.

Una vez ejecutadas las instrucciones en el servidor, un nuevo HTTP response se envía al navegador para mostrar lo que se ha solicitado. El resultado final es el mismo que en un sitio web estático: una página HTML que el usuario ve desde el navegador.

Más allá de esta definición, no existe una frontera clara entre lo que es contenido estático y dinámico. Debido a la evolución actual de la web se podría decir que todo el contenido es dinámico por la manera en que se crea. La proliferación de herramientas de publicación y de autoría de contenidos tales como los blogs convierten en dinámicos contenidos aparentemente estáticos.

Más info sobre las páginas dinámicas

Página dinámica vs Página estática

Página web estática: una página web (página HTML) que contiene la misma información para todos los usuarios. Aunque puede actualizarse periódicamente, no cambia con cada recuperación de usuario. Notarán que al interactuar con la página para acceder a más datos se producen cambios en la dirección URL.

Página web dinámica: una página web que proporciona contenido personalizado para el usuario en función de los resultados de una búsqueda o alguna otra solicitud. También conocido como HTML dinámico o contenido dinámico, el término dinámico se utiliza para referirse a páginas web interactivas creadas para cada usuario. Notarán que al interactuar con la página para acceder a más datos no se producen cambios en la dirección URL.

Introducción a Selenium

Selenium es un entorno de pruebas que se utiliza para comprobar si el software que se está desarrollando funciona correctamente. Esta herramienta permite: grabar, editar y depurar casos de pruebas que se pueden automatizar.

WebDriver es la interfaz básica para simular las interacciones del usuario con cualquier navegador, ya sea Firefox, Chrome, Edge, Safari o Internet Explorer. Desde 2018, la API es un estándar W3C oficial.

Más info sobre Selenium

Introducción al paquete {RSelenium}

{RSelenium} está diseñado para facilitar la conexión a un servidor Selenium o a un servidor Selenium remoto. {RSelenium} permite la conexión desde el entorno R a la API de Selenium Webdriver. Selenium es un proyecto que se centra en la automatización de los navegadores web.

{RSelenium} es imprescindible cuando nos enfrentamos a sitios web que son difíciles de rastrear porque extraen datos de forma dinámica de las bases de datos mediante JavaScript y jQuery. Por ejemplo, en sitios de redes sociales comunes como LinkedIn o Facebook, a medida que se desplaza hacia abajo en la página, se carga contenido nuevo y la URL no cambia. Estos sitios web son mucho más difíciles de scrapear. Una tarea de scraping fácil es cuando podemos ajustar la URL para cargar una nueva página en función de algún patrón sistemático.

Más info sobre el paquete {RSelenium}

Función rsDriver()

La función rsDriver() es una envoltura para la función selenium() del paquete wdman. Permite al usuario gestionar los binarios utilizados para ejecutar un servidor Selenium. Devuelve un entorno que contiene un “cliente” y un “servidor”.

Por defecto ejecuta un navegador Chrome. Se pueden seleccionar otros navegadores (Firefox, PhantomJS, Internet Explorer (Win)) utilizando el argumento browser.

El puerto por defecto en el que se ejecuta un Selenium Server usando la función rsDriver() es port = 4567L.

El siguiente paso es navegar hacia una dirección URL con la instancia de interacción de cliente selenium llamada navigate().

Una vez que la página se cargó podemos obtener su contenido con la función getPageSource().

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

Función para extraer nodos

Las funciones findElement() y findElements() permiten extraer con facilidad fragmentos de documentos HTML mediante los selectores XPath y CSS. El elemento ubicado se devolverá como un objeto de la clase “webElement”.

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

Función para extraer texto

La función getElementText() devuelve el texto visible del elemento que deseamos obtener en formato texto.

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

Función para extraer atributos de elementos HTML

getElementAttribute() obtiene el valor del atributo de un elemento como, por ejemplo, una dirección URL.

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

Otras funciones de {RSelenium}

Para navegar

goBack(): Equivalente a presionar el botón en el navegador.

goForward(): Equivalente a presionar el botón en el navegador.

refresh(): recargar la página actual.

maxWindowSize(): establece el tamaño de la ventana del navegador al máximo. De forma predeterminada, el tamaño de la ventana del navegador es pequeño y es posible que algunos elementos del sitio web al que navega no estén disponibles de inmediato.

Para scrapear

getCurrentUrl(): Recuperar la URL de la página actual.

getPageSource()[[1]]: Obtener la fuente de la página actual. Este método combinado con rvest es lo que hace posible extraer páginas web dinámicas. El documento XML devuelto por el método se puede leer usando rvest::read_html(). Este método devuelve un objeto de lista, esa es la razón detrás de [[1]].

Cierre y reapertura

close(): Cierra la sesión actual.

open(): para enviar una solicitud al servidor remoto y crear una instancia del navegador. Se usa este método cuando el navegador se cierra por alguna razón (por ejemplo, inactividad). Si ya ha iniciado el servidor Selenium, debe ejecutar esto en lugar de rsDriver() para volver a abrir el navegador.

Para interactuar con la página

sendKeysToElement(): para enviar una secuencia de pulsaciones de teclas a un elemento. Las pulsaciones de teclas se envían como una lista. El texto sin formato se ingresa como un elemento sin nombre de la lista. Las entradas del teclado se definen en selKeys y deben enumerarse con el nombre key.

clearElement(): para borrar el valor de un elemento TEXTAREA o INPUT de texto.

clickElement(): para hacer clic en un elemento. Puede hacer clic en enlaces, casillas de verificación, listas desplegables, etc.

Introducción al paquete {chromote}

{chromote} es una implementación en R del Chrome DevTools Protocol. Funciona con Chrome, Chromium, Opera, Vivaldi y otros navegadores basados en Chromium. Por defecto utiliza Google Chrome (que debe estar instalado en el sistema).

La interfaz de Chromote es similar a chrome-remote-interface para node.js.

Documentación oficial de {chromote}

Características principales de {chromote}

  • Instalación y uso de versiones específicas de Chrome desde Chrome for Testing
  • API síncrona para facilidad de uso y asíncrona para tareas más sofisticadas
  • Soporte completo para el Chrome DevTools Protocol para cualquier versión de Chrome
  • Métodos de conveniencia como $screenshot() y $set_viewport_size()
  • Reconexión automática a sesiones previas si se pierde la conexión
  • Base para otros paquetes como shinytest2 y rvest::read_html_live()

Funciones principales de ChromoteSession

Captura de pantalla

b$screenshot(): Captura una imagen de toda la página

b$screenshot(filename, selector): Captura una imagen de elementos específicos usando selectores CSS

b$screenshot_pdf(): Captura toda la página como PDF

# Captura de toda la página
b$screenshot("pagina_completa.png")

# Captura de un elemento específico
b$screenshot("sidebar.png", selector = ".sidebar")

# Captura de toda la página como PDF
b$screenshot_pdf("pagina_completa.pdf")

Nueva función de {rvest}: read_html_live()

read_html() opera sobre el código fuente HTML descargado del servidor. Esto funciona para la mayoría de los sitios web, pero puede fallar si el sitio usa JavaScript para generar HTML. read_html_live() proporciona una interfaz alternativa que ejecuta un navegador web activo (Chrome) en segundo plano. Esto le permite acceder a elementos de la página HTML que se generan dinámicamente mediante JavaScript e interactuar con la página en vivo haciendo clic en botones o completando formularios.

Detrás de la escena, esta función utiliza el paquete chromote, que requiere que tengas una copia de Google Chrome instalada en tu máquina.

Ventajas y desventajas de cada enfoque

{RSelenium}

Ventajas:

  • Control completo sobre el navegador
  • Capacidad para simular interacciones complejas del usuario
  • Compatibilidad con múltiples navegadores
  • Manejo avanzado de JavaScript y elementos dinámicos
  • Amplia documentación y comunidad establecida

Desventajas:

  • Configuración más compleja
  • Mayor consumo de recursos
  • Velocidad más lenta
  • Dependencias externas (drivers del navegador)
  • Manejo manual de la gestión de sesiones

{chromote}

Ventajas:

  • API moderna y eficiente
  • Soporte completo del Chrome DevTools Protocol
  • Reconexión automática a sesiones
  • Métodos de conveniencia integrados
  • Mejor gestión de recursos y memoria
  • Capacidades avanzadas de depuración

Desventajas:

  • Limitado a navegadores basados en Chromium
  • Curva de aprendizaje más empinada
  • Documentación menos extensa que RSelenium
  • API más técnica (requiere mayor conocimiento técnico)

{rvest} con read_html_live()

Ventajas:

  • Integración nativa con el ecosistema {rvest}
  • Configuración más simple
  • Sintaxis familiar para usuarios de {rvest}
  • Gestión automática del navegador Chrome
  • Ideal para casos de uso simples

Desventajas:

  • Limitado solo a Chrome
  • Funcionalidad más básica comparado con otras opciones
  • Menos control granular sobre las interacciones
  • Función relativamente nueva (menos documentación)

¿Cuándo usar cada herramienta?

Usa {RSelenium} cuando:

  • Necesites interacciones complejas (clicks, scroll, formularios)
  • Requieras compatibilidad con múltiples navegadores
  • El sitio web tenga elementos que aparecen con retraso
  • Tengas experiencia previa con Selenium
  • Necesites funcionalidades específicas bien documentadas

Usa {chromote} cuando:

  • Necesites máximo control y flexibilidad
  • Quieras aprovechar todas las capacidades del Chrome DevTools Protocol
  • Requieras capacidades avanzadas de depuración
  • Trabajes con aplicaciones web modernas complejas
  • Necesites funcionalidades como captura de pantalla avanzada
  • Prefieras una API más moderna y eficiente

Usa {rvest} con read_html_live() cuando:

  • Solo necesites acceder a contenido generado por JavaScript
  • Prefieras una solución más simple y rápida de implementar
  • Ya estés familiarizado con el ecosistema {rvest}
  • Chrome sea suficiente para tus necesidades
  • Busques una transición fácil desde scraping estático