Introducción

El objetivo de este documento es disponibilizar instrumentos para obtener precios de mercado y así poder comparar los productos existentes en el actual Convenio Marco de Compra de Computadores 2239-6-LR19.
Para este caso, los sitios consultados son los de PC Factory, Notebook Store, SP Digital, Mercado Tech, Winpy, Todo Click y Solo Todo, todas tiendas del mercado nacional de tecnología.

Web Scraping

A continuación se mostrará el código y el desarrollo de la obtención de los precios de mercado para ser replicado.

Entorno de Trabajo

Como es habitual, establecemos el directorio en el que vamos a trabajar y cargaremos las librerías (previamente instaladas) necesarias para estas tareas. En este caso, guardaremos los resultados y el script en la carpeta compartida “01Estrategia_y_Licitaciones_CM”. Si quien desee replicar el código no tenga acceso a esta carpeta o desee trabajar en otra, puede modificar la ruta en el código a su conveniencia:

setwd("//dccpsrvnas12/01Estrategia_y_Licitaciones_CM/Proyectos 2020/CONVENIOS MARCO/Precios CM Computadores")
library(tidyverse)
library(expss)
library(data.table)
library(readr)
library(tidytext)
library(stringr)
library(tidyr)
library(rvest)
library(pander)
library(curl)
library(magrittr)
library(writexl)
library(xlsx)

Exploración y Obtención de datos

En esta sección iremos recolectando los datos a partir de cada una de las fuentes de información anteriormente mencionadas. La forma en que aplicaremos el web scraping dependerá de la estructura de cada una de las páginas web:

PC Factory

Notebooks
#Nombre:
pcf.laptop.name <- lapply(paste0('https://www.pcfactory.cl/notebooks?categoria=735&papa=636&pagina=', 1:2),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".nombre") %>%
                   html_text() %>%
                   gsub('[\r\n\t]', '', .)
               })
pcf.laptop.name <- unlist(pcf.laptop.name)
#Precio: 
pcf.laptop.price <- lapply(paste0('https://www.pcfactory.cl/notebooks?categoria=735&papa=636&pagina=', 1:2),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".txt-precio") %>%
                   html_text()
               })
pcf.laptop.price <- unlist(pcf.laptop.price)
PCF.Laptop <- do.call(rbind, Map(data.frame, Nombre=pcf.laptop.name, Precio=pcf.laptop.price))
rownames(PCF.Laptop) <- c(1:85)
write_xlsx(PCF.Laptop,"pcf_laptop.xlsx")
Escritorio
#Nombre:
pcf.desktop.name <- lapply(paste0('https://www.pcfactory.cl/escritorio?categoria=737&papa=636&pagina=', 1:2),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".nombre") %>%
                   html_text() %>%
                   gsub('[\r\n\t]', '', .)
               })
pcf.desktop.name <- unlist(pcf.desktop.name)
#Precio: 
pcf.desktop.price <- lapply(paste0('https://www.pcfactory.cl/escritorio?categoria=737&papa=636&pagina=', 1:2),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".txt-precio") %>%
                   html_text()
               })
pcf.desktop.price <- unlist(pcf.desktop.price)
PCF.Desktop <- do.call(rbind, Map(data.frame, Nombre=pcf.desktop.name, Precio=pcf.desktop.price))
rownames(PCF.Desktop) <- c(1:57)
write_xlsx(PCF.Desktop,"pcf_desktop.xlsx")

Notebook Store

Nombre del Producto
ns.name <- lapply(paste0('https://notebookstore.cl/equipos/computadores-1.html?p=', 1:4),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".product-item-link") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
ns.name <- unlist(ns.name)
ns.name <- ns.name[ns.name != ""]
#ns.name <- as.data.frame(ns.name)
#ns.name <- ns.name[!(ns.name$ns.name==""),]
Precio
ns.price <- lapply(paste0('https://notebookstore.cl/equipos/computadores-1.html?p=', 1:4),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".price-wrapper .price") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) #%>%
               })
ns.price <- unlist(ns.price)
ns.price <- ns.price[ns.price != " cargando.. "]
#ns.price <- as.data.frame(ns.price)
#ns.price <- ns.price[!(ns.price$ns.price==""),]
Base de Datos de Notebook Store
NS <- do.call(rbind, Map(data.frame, Nombre=ns.name, Precio=ns.price))
rownames(NS) <- c(1:152)
#NS$Nombre <- gsub('+$', '',NS$Nombre)
write_xlsx(NS,"notebookstore.xlsx")

SP Digital

PC Escritorio
#Nombre:
sp.desktop.name <- lapply(paste0('https://www.spdigital.cl/categories/view/364/page:', 1:11),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".detail-center") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .) 
               })
sp.desktop.name <- unlist(sp.desktop.name)
#Precio: 
sp.desktop.price <- lapply(paste0('https://www.spdigital.cl/categories/view/364/page:', 1:11),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".cash-price-value") %>%
                   html_text() %>%
                   gsub('[\r\n\t]', '', .)
               })
sp.desktop.price <- unlist(sp.desktop.price)
SP.Desktop <- do.call(rbind, Map(data.frame, Nombre=sp.desktop.name, Precio=sp.desktop.price))
rownames(SP.Desktop) <- c(1:127)
write_xlsx(SP.Desktop,"SP_desktop.xlsx")
Notebook Corporativo y Comercial
#Nombre:
sp.corp.name <- lapply(paste0('https://www.spdigital.cl/categories/view/365/page:', 1:53),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".detail-center") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .) 
               })
sp.corp.name <- unlist(sp.corp.name)
#Precio: 
sp.corp.price <- lapply(paste0('https://www.spdigital.cl/categories/view/365/page:', 1:53),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".cash-price-value") %>%
                   html_text() %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('+$', '', .)
               })
sp.corp.price <- unlist(sp.corp.price)
sp.corp.price <- sp.corp.price %>% 
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
SP.Laptop <- do.call(rbind, Map(data.frame, Nombre=sp.corp.name, Precio=sp.corp.price))
rownames(SP.Laptop) <- c(1:632)
write_xlsx(SP.Laptop,"SP_laptop.xlsx")
All In One
#Nombre:
sp.aio.name <- lapply(paste0('https://www.spdigital.cl/categories/view/370/page:', 1:12),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".detail-center") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .) 
               })
sp.aio.name <- unlist(sp.aio.name)
#Precio: 
sp.aio.price <- lapply(paste0('https://www.spdigital.cl/categories/view/370/page:', 1:12),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".cash-price-value") %>%
                   html_text() %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('+$', '', .)
               })
sp.aio.price <- unlist(sp.aio.price)
sp.aio.price <- sp.aio.price %>% 
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
SP.AIO <- do.call(rbind, Map(data.frame, Nombre=sp.aio.name, Precio=sp.aio.price))
rownames(SP.AIO) <- c(1:136)
write_xlsx(SP.AIO,"SP_aio.xlsx")

Mercado Tech

Nombre del Producto
mt.name <- lapply(paste0('https://www.mercadotech.cl/t/tecnologia/equipos?current_store_id=7&page=', 1:8),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".product-component-name") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
mt.name <- unlist(mt.name)
Precio
mt.price <- lapply(paste0('https://www.mercadotech.cl/t/tecnologia/equipos?current_store_id=7&page=', 1:8),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".product-component-price") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) #%>%
               })
mt.price <- unlist(mt.price)
Base de Datos de Mercado Tech
MT <- do.call(rbind, Map(data.frame, Nombre=mt.name, Precio=mt.price))
rownames(MT) <- c(1:165)
write_xlsx(MT,"mercadotech.xlsx")

Winpy

Nombre del Producto
w.name <- lapply(paste0('https://www.winpy.cl/computadores/paged/', 1:4, '/'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("h2 a") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
w.name <- unlist(w.name)
Precio
w.price <- lapply(paste0('https://www.winpy.cl/computadores/paged/', 1:4, '/'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".valor") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) #%>%
               })
w.price <- unlist(w.price)
Base de Datos de Winpy
W <- do.call(rbind, Map(data.frame, Nombre=w.name, Precio=w.price))
rownames(W) <- c(1:65)
write_xlsx(W,"winpy.xlsx")

Todo Click

Nombre del Producto
tc.name <- lapply(paste0('https://todoclick.cl/computacion/page/', 1:4, '/'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".woocommerce-loop-product__title") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
tc.name <- unlist(tc.name)
Precio
tc.price <- lapply(paste0('https://todoclick.cl/computacion/page/', 1:4, '/'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes(".price") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) #%>%
               })
tc.price <- unlist(tc.price)
Base de Datos de Todo Click
TC <- do.call(rbind, Map(data.frame, Nombre=tc.name, Precio=tc.price))
rownames(TC) <- c(1:49)
write_xlsx(TC,"todoclick.xlsx")

Finalmente, nos queda hacer un web scraping de “Solo Todo”, sitio diferente a los demás ya que recopila información de otras páginas de venta de computadores y que estructura las características de los productos de manera diferente. Dicho esto, la programación para obtener los datos variará respecto a lo que se ha mostrado anteriormente:

Solo Todo

En este caso partiremos con los notebooks, para posteriormente realizar los mismos pasos y así obtener la información de los otros ítemes.

Notebooks
Marca y Modelo
Nombre <- lapply(paste0('https://www.solotodo.cl/notebooks?ordering=offer_price_usd&page=', 1:55, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("#category-browse-results-card h3") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
Nombre <- unlist(Nombre)
Procesador
Procesador <- lapply(paste0('https://www.solotodo.cl/notebooks?ordering=offer_price_usd&page=', 1:55, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("dd:nth-child(2)") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
Procesador <- unlist(Procesador)
Pantalla
Pantalla <- lapply(paste0('https://www.solotodo.cl/notebooks?ordering=offer_price_usd&page=', 1:55, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("dd:nth-child(4)") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
Pantalla <- unlist(Pantalla)
RAM
RAM <- lapply(paste0('https://www.solotodo.cl/notebooks?ordering=offer_price_usd&page=', 1:55, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("dd:nth-child(6)") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
RAM <- unlist(RAM)
Almacenamiento
Almacenamiento <- lapply(paste0('https://www.solotodo.cl/notebooks?ordering=offer_price_usd&page=', 1:55, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("dd:nth-child(8)") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
Almacenamiento <- unlist(Almacenamiento)
Precio
Precio <- lapply(paste0('https://www.solotodo.cl/notebooks?ordering=offer_price_usd&page=', 1:55, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("#category-browse-results-card .flex-grow a") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) #%>%
               })
Precio <- unlist(Precio)
ST.Notebook <- do.call(rbind, Map(data.frame, 
                                  Nombre=Nombre,
                                  Procesador=Procesador,
                                  Pantalla=Pantalla,
                                  RAM=RAM,
                                  Almacenamiento=Almacenamiento,
                                  Precio=Precio))
rownames(ST.Notebook) <- c(1:630)
write_xlsx(ST.Notebook,"solotodo_notebook.xlsx")
All In One
Marca y Modelo
Nombre.a <- lapply(paste0('https://www.solotodo.cl/all_in_ones?ordering=offer_price_usd&page=', 1:9, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("#category-browse-results-card h3") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
Nombre.a <- unlist(Nombre.a)
Procesador
Procesador.a <- lapply(paste0('https://www.solotodo.cl/all_in_ones?ordering=offer_price_usd&page=', 1:9, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("dd:nth-child(2)") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
Procesador.a <- unlist(Procesador.a)
Pantalla
Pantalla.a <- lapply(paste0('https://www.solotodo.cl/all_in_ones?ordering=offer_price_usd&page=', 1:9, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("dd:nth-child(4)") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
Pantalla.a <- unlist(Pantalla.a)
RAM
RAM.a <- lapply(paste0('https://www.solotodo.cl/all_in_ones?ordering=offer_price_usd&page=', 1:9, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("dd:nth-child(6)") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
RAM.a <- unlist(RAM.a)
Almacenamiento
Almacenamiento.a <- lapply(paste0('https://www.solotodo.cl/all_in_ones?ordering=offer_price_usd&page=', 1:9, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("dd:nth-child(8)") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) %>%
                   gsub('^ +', '', .) %>%
                   gsub('+$', '', .)
               })
Almacenamiento.a <- unlist(Almacenamiento.a)
Precio
Precio.a <- lapply(paste0('https://www.solotodo.cl/all_in_ones?ordering=offer_price_usd&page=', 1:9, '&'),
               function(url){
                 url %>% read_html() %>%
                   html_nodes("#category-browse-results-card .flex-grow a") %>%
                   html_text() %>%
                   gsub("\\s+"," ", .) %>%
                   gsub('[\r\n\t]', '', .) #%>%
               })
Precio.a <- unlist(Precio.a)
ST.AIO <- do.call(rbind, Map(data.frame, 
                                  Nombre=Nombre.a,
                                  Procesador=Procesador.a,
                                  Pantalla=Pantalla.a,
                                  RAM=RAM.a,
                                  Almacenamiento=Almacenamiento.a,
                                  Precio=Precio.a))
rownames(ST.AIO) <- c(1:108)
write_xlsx(ST.AIO,"solotodo_allinone.xlsx")