Curso

Web Scraping con R y RStudio

Scraping de Google News con R y Rvest

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

1º de julio de 2025

Centro de Estudios Andaluces

Objetivos

  • Comprender los fundamentos del web scraping aplicado a fuentes de noticias.
  • Dominar dos métodos para extraer datos de Google News: Scraping directo (HTML) y Scraping de Feeds RSS (XML).
  • Comparar las ventajas y desventajas de cada método.

¿Por qué Google News?

Google News es uno de los agregadores de noticias más grandes del mundo. Hacer scraping de esta fuente nos permite recolectar datos noticiosos de forma masiva y automatizada:

  • Extracción masiva de datos por tópico: Configurar scrapers que recolecten automáticamente miles de artículos diarios filtrados por categorías específicas, procesando múltiples fuentes internacionales simultáneamente.
  • Monitoreo automatizado de menciones: Implementar sistemas de scraping que rastreen 24/7 menciones específicas usando términos clave y filtros avanzados en tiempo real.
  • Análisis de tendencias en tiempo real: Desarrollar scrapers que capturen el flujo continuo de noticias para identificar patrones emergentes y picos de interés automáticamente.
  • Scraping geolocalizado y multilingüe: Implementar scrapers especializados que extraigan noticias segmentadas por regiones geográficas y diferentes idiomas para análisis comparativos internacionales.

Dos enfoques

  1. Scraping directo (HTML)

Consiste en descargar y analizar el código HTML de la página de resultados de Google News, tal como la ve un usuario en su navegador.

  • Ventaja: Acceso a toda la información visible.
  • Desventaja: Frágil, pesado y propenso a bloqueos.

  1. Feeds RSS (XML)

Consiste en consumir un feed de datos estructurado (XML) que Google News provee específicamente para sindicación de contenido.

  • Ventaja: Rápido, ligero, estable y diseñado para ser leído por máquinas.
  • Desventaja: Menos datos (ej. no incluye imágenes de la miniatura).

Fundamentos: URLs de búsqueda

Entender cómo se construyen las URLs es clave para automatizar las búsquedas.

URL para búsqueda directa (HTML):

https://news.google.com/search?q={término}&hl={idioma}&gl={país}

URL para Feeds RSS (XML):

https://news.google.com/rss/search?q={término}&hl={idioma}&gl={país}

Parámetros importantes:

  • q: El término de búsqueda. Los espacios se codifican como %20 o +.
  • hl: Idioma (ej. es para español, en-US para inglés de EE.UU.).
  • gl: Geolocalización (país, ej. AR para Argentina, US para EE.UU.).
  • when: Periodo de tiempo (ej. when:7d para los últimos 7 días).

Scraping directo de Google News

Para el scraping directo, debemos “inspeccionar” la página y encontrar los selectores CSS o XPath que identifican de forma única los elementos que queremos extraer.

Pasos:

  1. Ve a Google News y realiza una búsqueda.
  2. Haz clic derecho en un titular y selecciona “Inspeccionar”.
  3. Se abrirán las herramientas de desarrollador. Busca la estructura HTML que contiene los datos.

Elementos a buscar:

  • El contenedor de cada artículo de noticia.
  • El selector para el título.
  • El selector para la fuente de la noticia.
  • El selector para la fecha o tiempo de publicación.

Scraping directo: código base

Usamos rvest para leer el HTML y extraer los nodos. El proceso básico es:

  • read_html() para descargar la página.
  • html_elements() para seleccionar los contenedores de cada noticia.
  • Iterar sobre cada contenedor para extraer los datos específicos.
# URL de búsqueda para "inteligencia artificial" en español para Argentina
url <- "https://news.google.com/search?q=inteligencia%20artificial&hl=es-419&gl=AR"

# 1. Leer el HTML de la página
pagina_html <- read_html(url, encoding = "UTF-8")

# 2. Identificar los contenedores de cada artículo
articulos <- html_elements(pagina_html, "article")

# 3. Extraer el título del primer artículo como ejemplo
articulos |> (\(x) x[[1]])() |> # Seleccionamos el primer artículo
  html_element(".JtKRv") |> # Buscamos el enlace dentro de la clase JtKRv
  html_text2() # Extraemos el texto

Problemas comunes del scraping directo

El scraping directo es frágil.

  • Cambios en el diseño (layout): Google puede cambiar el diseño de su página en cualquier momento, rompiendo tus selectores CSS/XPath. Tu script dejará de funcionar sin previo aviso.
  • Contenido dinámico (JS): Muchas páginas modernas cargan su contenido usando JavaScript después de que la página inicial se haya cargado. read_html solo ve el HTML inicial, por lo que puede que no vea todo el contenido. Para esto se necesitarían funciones más complejas como read_html_live.
  • Bloqueos de IP: Realizar muchas peticiones en poco tiempo puede hacer que Google te identifique como un bot y bloquee tu dirección IP temporalmente, devolviendo un error HTTP.

¿Qué son los Feeds RSS?

RSS (Really Simple Syndication) es un formato de archivo basado en XML diseñado para compartir contenido actualizado, como noticias o posts de blogs.

¡Es una API no oficial y gratuita!

Ventajas para el Scraping:

  • Estructurado: Los datos ya vienen en un formato predecible y fácil de analizar (título, link, descripción, fecha). No hay que “adivinar” selectores CSS.
  • Ligero y rápido: Un feed RSS es un archivo de texto simple, mucho más pequeño que una página HTML completa con CSS, JavaScript e imágenes. (30 KB vs ~1000 KB).
  • Robusto y estable: La estructura de un feed RSS rara vez cambia. Es mucho más fiable a largo plazo que el scraping de HTML.
  • Menor riesgo de bloqueo: Están diseñados para ser consumidos por máquinas, por lo que es menos probable que te bloqueen.

URLs de RSS de Google News

La URL base para los feeds RSS es https://news.google.com/rss/search. Podemos añadir parámetros para personalizar la búsqueda de forma muy potente.

Ejemplo: Noticias sobre “RStudio” en las últimas 24 horas.

https://news.google.com/rss/search?q=RStudio+when:24h&hl=es-419&gl=AR

Podemos construir URLs dinámicamente en R para automatizar cualquier tipo de búsqueda.

RSS: scraping de RSS con xml2

En lugar de rvest, usamos la librería xml2, que está optimizada para trabajar con archivos XML. La estructura de un feed RSS es estándar.

Estructura típica de un item de RSS:
<item>
  <title>El increíble avance de R en la ciencia de datos</title>
  <link>https://ejemplo.com/noticia-r</link>
  <pubDate>Tue, 26 Oct 2023 10:00:00 GMT</pubDate>
  <description>Un resumen de la noticia...</description>
  <source url="https://ejemplo.com">Noticias de Ejemplo</source>
</item>

El proceso con xml2 es:
1. read_xml() para descargar y parsear el feed.
2. xml_find_all(“.//item”) para obtener una lista de todas las noticias.
3. xml_find_first() y xml_text() para extraer los datos de cada etiqueta (title, link, etc.).

RSS: código base

El código es más simple y predecible que el de scraping HTML.

# URL para noticias sobre "R-Project"
url_rss <- "https://news.google.com/rss/search?q=R-Project&hl=es-419&gl=AR"

# 1. Leer el XML
feed_xml <- read_xml(url_rss)

# 2. Encontrar todos los items de noticias
items <- xml_find_all(feed_xml, ".//item")

# 3. Extraer el título del primer item como ejemplo
items |> (\(x) x[[1]])() |> xml_find_first(".//title") |> xml_text()

SD vs RSS

Característica Scraping directo (HTML) Feeds RSS (XML)
Estabilidad Baja (se rompe con cambios de diseño) Alta (formato estándar y estable)
Velocidad/Eficiencia Lento (descarga HTML, CSS, JS) Muy rápido (solo texto estructurado)
Complejidad código Alta (depende de selectores frágiles) Baja (estructura predecible)
Riesgo de bloqueo Alto Bajo (diseñado para máquinas)
Riqueza de datos Alta (acceso a todo lo visible) Media (datos esenciales, no visuales)
Recomendación Usar solo si RSS no está disponible Método preferido siempre que sea posible

Automatización

Una vez que tu script funciona, el siguiente paso es automatizarlo para que se ejecute periódicamente.

  • Cron Jobs: Son tareas programadas que se ejecutan en un servidor en momentos específicos (ej. cada hora, todos los días a las 8 AM). En R, el paquete cronR es una excelente interfaz para gestionar cron jobs desde RStudio (en Linux/Mac).
  • Almacenamiento de Datos: No guardes los resultados en variables en memoria. Almacénalos de forma persistente.
    • Archivos CSV: Fácil y rápido. Usa readr::write_csv(…, append = TRUE) para añadir nuevos resultados a un archivo existente.
    • Bases de Datos: Para proyectos más grandes, usa paquetes como DBI y RSQLite (o RPostgres) para guardar los datos en una base de datos SQL. Es más robusto y escalable.

Mejores prácticas

Para asegurar que tus scripts sean robustos:

  1. Prefiere RSS sobre HTML siempre. Es la regla de oro.
  2. Limita la frecuencia de tus peticiones. Usa Sys.sleep() entre llamadas para no sobrecargar el servidor. for (query in queries) { Sys.sleep(2); … }
  3. Usa un User-Agent descriptivo. Usa httr::user_agent() en tus peticiones para identificarte.
  4. Maneja errores elegantemente. Envuelve tu código en bloques try() o tryCatch() para que tu script no se detenga si una petición falla.
  5. Guarda tus datos de forma incremental y no vuelvas a descargar lo que ya tienes.