# Librerías necesarias
library(jsonlite)
library(htmlwidgets)
library(httr)
library(rvest)
library(xml2)
library(stringr)
library(flexdashboard)
library(ggplot2)
library(highcharter)
library(tidyverse)
library(dplyr)
library(lubridate)
library(wordcloud2)
library(ggraph)
library(igraph)
library(tm)
library(plotly)
library(tidytext)
library(textdata)
# URL
<- "https://www.booking.com/city/mx/mexico.es-ar.html?aid=1234230"
url <- read_html(url)
pagina
# Scraping: encabezados
<- pagina %>%
nom.prod html_nodes('div.ff0d627d92') %>%
html_nodes('a') %>%
html_text2()
# Scraping: descripciones
<- pagina %>%
desc.prod html_nodes('div.ff0d627d92') %>%
html_nodes('p.b99b6ef58f.cdac6d30fc') %>%
html_text2()
# Scraping: precios
<- pagina %>%
valor html_nodes('div.ab35512885 div.f54cd6e81f span.de73b3d2d3.f82d0d24de') %>%
html_text2() %>%
gsub("[^0-9,]", "", .) %>%
gsub(",", ".", .) %>%
as.numeric()
# Uniendo datos
<- data.frame(articulo = nom.prod,
booking descripcion = desc.prod,
precio = valor) %>%
filter(!is.na(precio))
Tarea web scrapping - Análisis de Hoteles en CDMX desde Booking
El link url proporcionado para el taller es la página web de bookings y despliega título, descripción y precio de hoteles. Por lo que se descargaron los 3 parámetros en un dataframe.
Gráfico de precios
highchart() %>%
hc_chart(type = 'line') %>%
hc_xAxis(categories = booking$articulo) %>%
hc_add_series(name = "Precios Actuales", data = booking$precio, dataLabels = list(enabled = TRUE)) %>%
hc_credits(enabled = TRUE, text = 'booking.com', href = url) %>%
hc_exporting(enabled = TRUE)
La línea sube y baja, lo que indica que no hay un tendencia constante de precios; hay hoteles baratos y caros distribuidos a lo largo del listado.
Histograma y Boxplot de precios
hist(booking$precio, col = "skyblue", xlab = "USD", border = "white")
Se observa una concentración de precios bajos, especialmente entre 50 y 70 USD, lo cual sugiere que muchos alojamientos económicos están disponibles.
Hay precios más altos que generan la distribución hacia la derecha, aunque son menos frecuentes.
El promedio (91.80 USD) está ligeramente por debajo del valor del tercer cuartil (110.42).
boxplot(booking$precio, horizontal = TRUE, col = "orange")
El 50% central de los precio va del 1er cuartil (60.80) al 3er cuartil (110.42).
Línea dentro de la caja: La mediana (92.59), ligeramente desplazada hacia el extremo inferior, lo que indica una leve concentración de precios bajos.
Extremos (bigotes): Se extienden hacia el mínimo (52.21) y el máximo (159.20).
summary(booking$precio)
Min. 1st Qu. Median Mean 3rd Qu. Max.
52.21 60.80 92.59 91.80 110.42 159.20
Hay bastante variación: los precios van desde $52.21 hasta $159.20.
La media (~91.8) está muy cerca de la mediana (~92.6) lo que sugiere que la distribución es más o menos simétrica.
El rango intercuartílico (Q3 - Q1) es de 49.62 USD, indicando dispersión en el 50% central de los hoteles.
Puede haber algunos precios altos que estiran el máximo, pero no son extremos exagerados.
Análisis de texto: Títulos y descripciones con WordCloud
# Preprocesamiento títulos
<- booking$articulo %>%
booking_1 iconv(to = "ASCII", sub = "") %>%
tolower() %>%
removeWords(words = stopwords("spanish")) %>%
removePunctuation() %>%
removeNumbers() %>%
stripWhitespace()
<- Corpus(VectorSource(booking_1)) %>%
corpus tm_map(removeWords, stopwords("spanish")) %>%
tm_map(removeNumbers) %>%
tm_map(stemDocument)
<- DocumentTermMatrix(corpus)
dtm <- dtm[apply(dtm, 1, sum) > 1,]
dtm <- colSums(as.matrix(dtm))
freq <- data.frame(words = names(freq), count = freq)
plot <- subset(plot, count > 1)
plot
# Preprocesamiento descripciones
<- booking$descripcion %>%
booking_2 iconv(to = "ASCII", sub = "") %>%
tolower() %>%
removeWords(words = stopwords("spanish")) %>%
removePunctuation() %>%
removeNumbers() %>%
stripWhitespace()
<- Corpus(VectorSource(booking_2)) %>%
corpus2 tm_map(removeWords, stopwords("spanish")) %>%
tm_map(removeNumbers) %>%
tm_map(stemDocument)
<- DocumentTermMatrix(corpus2)
dtm2 <- dtm2[apply(dtm2, 1, sum) > 1,]
dtm2 <- colSums(as.matrix(dtm2))
freq2 <- data.frame(words = names(freq2), count = freq2)
plot2 <- subset(plot2, count > 1) plot2