The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

twscrapeR

Twitter/X Scraping for R via Python’s twscrape

R Python License

📖 Tabla de Contenidos

🌟 Características

📦 Instalación

# Instalar desde GitHub
library(devtools)
install_github("agusnieto77/twscrapeR")

Requisito importante del entorno Python: usá twscrape >= 0.18.0 con Python >= 3.10. La versión twscrape 0.17.0 quedó rota para SearchTimeline después de cambios en X/Twitter y puede fallar con IndexError: list index out of range. Desde twscrape 0.18.0, el fix viene upstream y twscrapeR ya no necesita aplicar un monkeypatch local.

Instalá o actualizá twscrape fuera de las funciones del paquete, por ejemplo en una terminal:

python -m pip install "twscrape>=0.18.0"

🚀 Inicio Rápido (3 Pasos)

Paso 1: Configuración Inicial

library(twscrapeR)

# Configuración guiada (solo verifica el entorno; no instala software)
setup_twscraper()

La función setup_twscraper() te guiará a través de: 1. Detección de Python >= 3.10 2. Verificación de la librería Python twscrape 3. Configuración del entorno

Si no tenés Python o twscrape instalado, setup_twscraper() mostrará instrucciones para instalarlo manualmente fuera de R.

Paso 2: Agregar Cuenta

Opción recomendada: guardá tus credenciales en .Renviron y agregá la cuenta sin escribir secretos en el script.

# En .Renviron
TWS_USERNAME='tu_usuario'
TWS_PASSWORD='tu_password'
TWS_EMAIL='tu@email.com'
TWS_EMAIL_PASSWORD='email_pass'
# Opción A: cookie completa
TWS_COOKIES='auth_token=valor_auth_token; ct0=valor_ct0'

# Opción B: valores separados; add_account_from_env() arma la cookie
TWS_AUTH_TOKEN='valor_auth_token'
TWS_CT0='valor_ct0'

# En R
add_account_from_env()

Para varias cuentas podés repetir el esquema con otro prefijo y pasarlo a la función, por ejemplo TWS2_USERNAME, TWS2_PASSWORD, TWS2_COOKIES, etc. y luego add_account_from_env(prefix = "TWS2_").

También podés pasar todo explícitamente:

add_account(
  username = "tu_usuario",
  password = "tu_password",
  email = "tu@email.com",
  email_password = "email_pass",
  cookies = "auth_token=...; ct0=..."
)

Nota IMPORTANTE: Las cookies son OBLIGATORIAS para que la cuenta se active correctamente. Podés pasarlas como TWS_COOKIES o como TWS_AUTH_TOKEN + TWS_CT0.

¿Cómo obtener cookies?

  1. Abre https://x.com en tu navegador (con sesión iniciada)
  2. Presiona F12 → “Application” → “Cookies” → “https://x.com”
  3. Copia los valores de auth_token y ct0
  4. Formato: "auth_token=valor1; ct0=valor2"

Paso 3: ¡Usar!

# Buscar tweets
tweets <- search_tweets("rstats", n = 100)

# Por defecto busca Latest; para tweets destacados/populares usá Top
top_tweets <- search_tweets("rstats", n = 100, product = "Top")

# Convertir a dataframe
df <- to_dataframe(tweets)
View(df)

# Guardar
save_csv(tweets, "tweets_rstats.csv")

📖 Funciones Principales

Búsqueda de Tweets

# Búsqueda general
tweets <- search_tweets("machine learning", n = 100)

# Latest es el valor por defecto; Top devuelve resultados destacados/populares
latest <- search_tweets("machine learning", n = 100, product = "Latest")
top <- search_tweets("machine learning", n = 100, product = "Top")

# Por hashtag
tweets <- search_hashtag("rstats", n = 50)
tweets <- search_hashtag("#datascience", n = 100)  # Con o sin #

# Menciones de un usuario
mentions <- search_mentions("hadleywickham", n = 50)

# Búsquedas avanzadas
tweets <- search_tweets("rstats lang:en", n = 100)  # Solo inglés
tweets <- search_tweets("from:hadleywickham", n = 50)    # De un usuario específico

Tweets de Usuario

# Obtener tweets de un usuario
tweets <- user_tweets("hadleywickham", n = 100)

# Ver información del usuario
user <- get_user("hadleywickham")
print(user)

Gestión de Cuentas

# Listar cuentas configuradas
list_accounts()

# Eliminar una cuenta
delete_account("usuario")

Conversión y Exportación

# Convertir a dataframe
df <- to_dataframe(tweets)

# Guardar como CSV
save_csv(tweets, "tweets.csv")

# Guardar como JSON
save_json(tweets, "tweets.json")

Filtrado y Ordenamiento

# Filtrar por idioma
tweets_es <- filter_by_lang(tweets, "es")
tweets_en <- filter_by_lang(tweets, "en")

# Filtrar por fecha
tweets_recent <- filter_by_date(tweets, from = "2025-10-01")
tweets_range <- filter_by_date(tweets, from = "2025-10-01", to = "2025-10-26")

# Ordenar por likes
top_tweets <- sort_tweets(tweets, by = "like_count")

# Ordenar por fecha (más recientes primero)
recent_first <- sort_tweets(tweets, by = "date", decreasing = TRUE)

📚 Referencia Completa de Funciones

1. Configuración y Cuentas (5 funciones)

# Configuración inicial del sistema
setup_twscraper()

# Agregar cuenta - se activa automáticamente con cookies
add_account_from_env()

# O pasar los datos explícitamente
add_account(
  username = "usuario",
  password = "pass",
  email = "email@example.com",
  email_password = "email_pass",
  cookies = "auth_token=...; ct0=..."  # OBLIGATORIO
)

# Listar todas las cuentas configuradas (muestra estado activo/inactivo)
accounts <- list_accounts()

# Eliminar una cuenta
delete_account("usuario")

# Verificar configuración del sistema
check_setup()

2. Búsqueda de Tweets (3 funciones)

# Búsqueda general de tweets; product acepta "Latest" o "Top"
tweets <- search_tweets("machine learning", n = 100)
top_tweets <- search_tweets("machine learning", n = 100, product = "Top")

# Buscar por hashtag
tweets <- search_hashtag("rstats", n = 50)
tweets <- search_hashtag("#datascience", n = 100)  # Con o sin #

# Buscar menciones a un usuario
mentions <- search_mentions("hadleywickham", n = 50)

3. Tweets de Usuario (3 funciones)

# Obtener tweets de un usuario
tweets <- user_tweets("rstudio", n = 100)

# Obtener tweets Y respuestas de un usuario
tweets_replies <- user_tweets_and_replies("hadleywickham", n = 100)

# Obtener solo tweets con media (imágenes/videos)
media_tweets <- user_media("NASA", n = 50)

4. Información de Usuarios (1 función)

# Obtener información detallada de un usuario
user <- get_user("hadleywickham")
print(user$followers_count)
print(user$following_count)
print(user$description)

5. Análisis de Tweets Específicos (4 funciones)

# Obtener detalles completos de un tweet
tweet_id <- "1234567890123456789"
details <- tweet_details(tweet_id)

# Obtener respuestas a un tweet
replies <- tweet_replies(tweet_id, n = 50)

# Obtener quién retuiteó un tweet
retweeters <- get_retweeters(tweet_id, n = 100)

# Obtener retweeters para varios tweets
tweets <- search_tweets("rstats", n = 10)
retweeters <- get_retweeters_batch(tweets, n = 50)
retweeters_df <- to_dataframe(retweeters)  # incluye source_tweet_id

# Si querés mantenerlos agrupados por tweet
retweeters_by_tweet <- get_retweeters_batch(tweets, n = 50, flatten = FALSE)

6. Análisis de Redes (3 funciones)

# Obtener seguidores de un usuario
followers <- get_followers("rstudio", n = 100)

# Obtener a quién sigue un usuario
following <- get_following("hadleywickham", n = 100)

# Obtener solo seguidores verificados
verified <- verified_followers("elonmusk", n = 50)

7. Conversión de Datos (1 función)

# Convertir tweets a dataframe
tweets <- search_tweets("rstats", n = 100)
df_tweets <- to_dataframe(tweets)

# También funciona con usuarios
followers <- get_followers("rstudio", n = 50)
df_users <- to_dataframe(followers)

8. Filtrado y Ordenamiento (3 funciones)

# Filtrar tweets por idioma
tweets_es <- filter_by_lang(tweets, "es")
tweets_en <- filter_by_lang(tweets, "en")

# Filtrar por fecha
tweets_recent <- filter_by_date(tweets, from = "2025-10-01")
tweets_range <- filter_by_date(
  tweets,
  from = "2025-10-01",
  to = "2025-10-26"
)

# Ordenar tweets
top_tweets <- sort_tweets(tweets, by = "like_count")
recent_tweets <- sort_tweets(tweets, by = "date", decreasing = TRUE)

9. Exportación (2 funciones)

# Guardar como CSV
save_csv(tweets, "tweets.csv")

# Guardar como JSON
save_json(tweets, "tweets.json")

📊 Análisis de Datos

Ejemplo Completo

library(twscrapeR)
library(dplyr)
library(ggplot2)

# 1. Configurar
setup_twscraper()
add_account(...)

# 2. Buscar tweets
tweets <- search_tweets("#rstats", n = 1000)

# 3. Convertir a dataframe
df <- to_dataframe(tweets)

# 4. Análisis con dplyr
df %>%
  filter(lang == "en") %>%
  arrange(desc(like_count)) %>%
  select(username, text, like_count, retweet_count) %>%
  head(10)

# 5. Visualización
df %>%
  count(date = as.Date(date)) %>%
  ggplot(aes(date, n)) +
  geom_line() +
  labs(title = "Tweets sobre #rstats por día",
       x = "Fecha", y = "Número de tweets")

# 6. Top usuarios
df %>%
  count(username, sort = TRUE) %>%
  head(10) %>%
  ggplot(aes(reorder(username, n), n)) +
  geom_col() +
  coord_flip() +
  labs(title = "Top 10 usuarios", x = "", y = "Tweets")

🔧 Solución de Problemas

Python no encontrado

Si setup_twscraper() no encuentra Python:

# Especificar ruta a Python ya instalado
setup_twscraper(python_path = "C:/Python/python.exe")

Instalá Python 3.10+ manualmente desde https://www.python.org/downloads/ o con tu gestor de entornos preferido. Después instalá twscrape en ese entorno y ejecutá setup_twscraper() nuevamente.

Verificar configuración

# Verificar si todo está correcto
check_setup()

# Ver configuración de Python
reticulate::py_config()

Cuenta no activa

Si una cuenta aparece como active = FALSE:

# 1. Listar cuentas para ver el estado
list_accounts()

# 2. Eliminar la cuenta inactiva
delete_account("usuario")

# 3. Volver a agregarla CON cookies válidas y actuales
add_account(
  username = "usuario",
  password = "pass",
  email = "email@example.com",
  email_password = "email_pass",
  cookies = "auth_token=...; ct0=..."  # OBLIGATORIO
)

Importante: - Las cookies son OBLIGATORIAS para activar cuentas - Si una cuenta no se activa, las cookies están expiradas o son inválidas - Obtén nuevas cookies desde tu navegador (ver sección “¿Cómo obtener cookies?”)

Rate Limiting

Twitter/X aplica límites por tipo de consulta y twscrape los administra por cola. Si ves un mensaje como este:

No account available for queue "Followers". Next available at 20:25:08

significa que todas las cuentas disponibles para esa cola llegaron temporalmente a su límite. No es un error de R: hay que esperar o distribuir mejor la carga.

Qué hacer:

  1. Bajá n: empezá con valores chicos (n = 50 o n = 100) y subí de a poco.
  2. Agregá más cuentas válidas: twscrape rota automáticamente entre cuentas activas.
  3. Verificá tus cuentas: usá list_accounts() y confirmá que aparezcan como active = TRUE.
  4. Esperá el reset: el propio mensaje indica cuándo vuelve a estar disponible la cola.

Ejemplo con varias cuentas:

add_account("usuario1", "pass1", "email1@example.com", "email_pass1", "auth_token=...; ct0=...")
add_account("usuario2", "pass2", "email2@example.com", "email_pass2", "auth_token=...; ct0=...")

list_accounts()

No hay un número universal que evite siempre el bloqueo: depende de la cola (Search, Followers, UserTweets, etc.), de la edad/estado de las cuentas y de la carga reciente. La regla práctica es pedir lotes más chicos y dejar que la rotación haga su trabajo.

Error IndexError: list index out of range en twscrape

X/Twitter cambia con frecuencia sus bundles web. En twscrape 0.17.0 eso puede romper el cálculo interno de x-client-transaction-id y bloquear consultas reales aunque la cuenta figure activa.

La solución actual es usar twscrape >= 0.18.0, donde el arreglo ya viene incluido upstream. twscrapeR no aplica un monkeypatch local para este caso.

python -m pip install "twscrape>=0.18.0"
setup_twscraper()

Después de actualizar, una prueba corta como search_tweets("Milei", n = 5) debería funcionar si la cuenta y las cookies están activas.

📚 Estructura de Datos

Tweet Object

tweet <- tweets[[1]]
str(tweet)

Campos disponibles: - id: ID del tweet - date: Fecha y hora (POSIXct) - text: Texto completo del tweet - username: Usuario que publicó - user_displayname: Nombre mostrado del usuario - user_id: ID del usuario - reply_count: Número de respuestas - retweet_count: Número de retweets - like_count: Número de likes - quote_count: Número de quote tweets - views_count: Número de vistas - lang: Idioma del tweet - url: URL del tweet - user_followers: Seguidores del usuario - user_verified: Usuario verificado (TRUE/FALSE)

User Object

user <- get_user("username")
str(user)

Campos: - id: ID del usuario - username: @usuario - displayname: Nombre mostrado - description: Biografía - followers_count: Seguidores - following_count: Siguiendo - tweets_count: Total de tweets - verified: Cuenta verificada - created: Fecha de creación - location: Ubicación - url: URL del perfil - profile_image_url: URL de la foto de perfil

🤝 Contribuciones

Las contribuciones son bienvenidas! Por favor:

  1. Fork el repositorio
  2. Crea una rama para tu feature (git checkout -b feature/AmazingFeature)
  3. Commit tus cambios (git commit -m 'Add some AmazingFeature')
  4. Push a la rama (git push origin feature/AmazingFeature)
  5. Abre un Pull Request

📄 Licencia

MIT License - ver archivo LICENSE

🙏 Agradecimientos

twscrapeR es posible gracias a dos proyectos excepcionales de Python:

Y al ecosistema de R:

📧 Soporte

⚠️ Disclaimer

Este paquete es para propósitos educativos y de investigación. Asegúrate de cumplir con los términos de servicio de Twitter/X al usarlo.


These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.