Conferencia virtual

Extracción de datos con web scraping para la investigación en ciencias sociales: aplicaciones prácticas

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

20 de febrero de 2025

Financian: Proyecto NON-CONSPIRA-HATE! (Ref. PID2021-123983OB-I00) y Grupo ESEIS/EPIT-2025.

Web Scraping en un escenario post-API

Las recientes restricciones en el acceso a las APIs de redes sociales han afectado profundamente a la investigación digital y las ciencias sociales computacionales. Plataformas como Twitter y Facebook han reducido o eliminado el acceso gratuito a sus APIs, lo que obliga a los investigadores a encontrar nuevas formas de acceder a los datos. En este contexto, surge la “era post-API”, donde los estudios sociales se ven limitados por la disponibilidad de datos y los altos costos para obtenerlos.

¿Cuánto cambio realmente nuestra relación con los datos de las RRSS?

Según Tromble (2021), poco. En sus palabras: “La relación subyacente entre los investigadores, las plataformas y los datos digitales sigue siendo en gran medida la misma. Las plataformas y sus API siempre han sido cajas negras propietarias, nunca pensadas para uso académico. Incluso cuando los investigadores podían extraer datos de forma aparentemente interminable, rara vez sabíamos qué tipo o calidad de datos teníamos a mano. Es más, la generosidad de la era API permitió a muchos investigadores realizar su trabajo con poco respeto por el rigor, la ética o el enfoque en el valor social que deberíamos esperar de la investigación académica. En otras palabras, nuestros procesos y resultados de investigación digital no siempre han ocupado un lugar destacado. En lugar de ver el año 2018 y a Cambridge Analytica como una profunda disyuntiva y pérdida, sugiero que los investigadores digitales deben adoptar una mirada más crítica sobre cómo nuestra comunidad recopiló y analizó datos cuando todavía parecían tan abundantes, y utilizar estas reflexiones para informar nuestros enfoques en el futuro.”

El renacer del Web Scraping

El web scraping, una técnica tradicionalmente utilizada para extraer datos directamente desde sitios web, ha ganado relevancia como solución alternativa frente a las restricciones de las APIs. Aunque históricamente subestimado en la investigación social, el scraping ha demostrado ser un recurso esencial para recolectar datos tanto en tiempo real como históricos de plataformas de redes sociales.

Con las APIs restringidas, el scraping ofrece a lxs investigadorxs una forma accesible y flexible para continuar obteniendo datos relevantes para el análisis social. Sin embargo, también presenta desafíos, tanto éticos como legales, en cuanto a la privacidad de lxs usuarixs y el cumplimiento de los términos de servicio de las plataformas.

Tjaden (2023) sostiene que “a medida que los grandes proveedores de datos digitales como Facebook o Twitter restringen cada vez más el acceso a sus datos para los investigadores, el web scraping cobrará mayor importancia en el futuro y merece su lugar en la caja de herramientas de los académicos de migración y movilidad.”

Desafíos de la era post-API

El principal desafío que plantea la era post-API es el acceso a los datos. Las APIs, que antes permitían a lxs investigadorxs obtener información estructurada y autorizada de las redes sociales, ahora exigen pagos considerables o han reducido sus funcionalidades gratuitas. Esto ha creado una barrera de entrada para los estudios de datos sociales a gran escala, particularmente para aquellos con recursos limitados.

En este nuevo contexto, el scraping se ha posicionado como una alternativa viable, pero no sin sus dificultades. La necesidad de cumplir con las normativas de privacidad y evitar el bloqueo por parte de las plataformas requiere de enfoques más sofisticados.

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

Web Scraping: ¿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()

¿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.

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}

¿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 es 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

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 escribiendo formularios.

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

¿Cómo nos puede ayudar ChatGPT?

ChatGPT puede ser una herramienta muy útil en el proceso de web scraping al ayudarnos a analizar y comprender la estructura HTML de las páginas web. Su capacidad para examinar el código fuente y sugerir los selectores CSS o XPath más efectivos nos permite identificar rápidamente los elementos que necesitamos extraer, además de proporcionar orientación sobre la mejor manera de navegar por la estructura DOM de la página. Esta asistencia es particularmente útil cuando nos enfrentamos a páginas web complejas o dinámicas que requieren un análisis detallado de su estructura.

Además, ChatGPT puede ayudarnos a generar y optimizar código de web scraping y ofrecer soluciones para manejar casos específicos como la extracción de datos dinámicos, la implementación de delays apropiados para respetar los servidores, y la gestión de errores comunes. También puede proporcionar orientación sobre buenas prácticas y consideraciones éticas en el web scraping.

Un ejemplo

Algunas aplicaciones prácticas

Observatorio de Conflictividad - PHP

Observatorio de Precios - PHP

Observatorio de Conflictividad - IA

TweetScraperR

Bibliografía de referencia

  • Achmann-Denkler & Wolff (2024) Preserving the Ephemeral: Instagram Story Archiving with the Tidal Tales Plugin. https://arxiv.org/html/2409.01880v1
  • Haans, R. F. J., & Mertens, M. J. (2024). The Internet Never Forgets: A Four-Step Scraping Tutorial, Codebase, and Database for Longitudinal Organizational Website Data. Organizational Research Methods, 0(0). https://doi.org/10.1177/10944281241284941
  • Haas-Mendoza, M., & Zanzzi, F. Let’s re-search. APIs and web-scraping. ResearchGate case. https://dx.doi.org/10.18687/LEIRD2024.1.1.721
  • Harrell, N. B., Cruickshank, I., & Master, A. (2024). Overcoming Social Media API Restrictions: Building an Effective Web Scraper. https://workshop-proceedings.icwsm.org/pdf/2024_72.pdf
  • Ledford, H. (2023). Researchers scramble as Twitter plans to end free data access. Nature, 614(7949), 602-603.
  • Mancosu & Vegetti (2020) What You Can Scrape and What Is Right to Scrape: A Proposal for a Tool to Collect Public Facebook Data. 3. https://doi.org/10.1177/2056305120940703
  • Muñoz-Villamizar, Piatti, Mejía-Argueta, Pirabe, Namdar, Gomez (2024) Navigating retail inflation in Brazil: A machine learning and web scraping approach to the basic food basket. Journal of Retailing and Consumer Services. Volume 79. https://doi.org/10.1016/j.jretconser.2024.103875
  • Murtfeldt, R., Alterman, N., Kahveci, I., & West, J. D. (2024). RIP Twitter API: A eulogy to its vast research contributions (arXiv:2404.07340). arXiv. https://doi.org/10.48550/arXiv.2404.07340
  • Nieto, A. (2024). TweetScraperR: una herramienta para la recolección de tweets en la era post-API. Rpub. https://rpubs.com/agustin/tweet-scraper
  • Perriam, J., Birkbak, A., & Freeman, A. (2019). Digital methods in a post-API environment. International Journal of Social Research Methodology, 23(3), 277–290. https://doi.org/10.1080/13645579.2019.1682840
  • Poudel & Weninger (2024) Navigating the Post-API Dilemma. In Proceedings of the ACM Web Conference 2024 (WWW ’24). Association for Computing Machinery, New York, NY, USA, 2476–2484. https://doi.org/10.1145/3589334.3645503
  • Tjaden, J. (2023). Web Scraping for Migration, Mobility, and Migrant Integration Studies: Introduction, Application, and Potential Use Cases. International Migration Review, 0(0). https://doi.org/10.1177/01979183231208428
  • Trezza D. (2023) To scrape or not to scrape, this is dilemma. The post-API scenario and implications on digital research. Front. Sociol. 8:1145038. doi: 10.3389/fsoc.2023.1145038
  • Tromble R. (2021) Where Have All the Data Gone? A Critical Reflection on Academic Digital Research in the Post-API Age. Social Media + Society. 1. https://doi.org/10.1177/2056305121988929
  • Willian A. S. Farias, Dulce M. A. Melo, Lamara M. dos Santos et al. (2024) Web Scraping as a scientific tool for theoretical reference, PREPRINT (Version 1) available at Research Square https://doi.org/10.21203/rs.3.rs-3854342/v1