Es común que al automatizar la obtención de datos te encuentres con errores, al final de cuentas no todas las páginas van a ser iguales. Para resolverlo de manera sencilla vamos a imprimir la url al inicio de la función, al momento de error la última url que se imprima será la responsable.
En este caso nuestro problema es que la página no cuenta con una tabla para obtener los datos de la aspiradora, en este caso simplemente vamos a asignar un -1 a los casos que no tengan la tabla.
Al momento de generar la matriz “articulo” el campo “nombre_texto” me aparece con saltos de línea y espacios en blanco, para corregirlo agregué el comando "trimws" para eliminar estas inconsistencias; el código modificado es el siguiente
articulo<-c(trimws(nombre_texto),as.character(mitab$`Peso del producto`[1]),as.character(mitab$`Dimensiones del producto`[1]),as.character(mitab$Volumen[1]),as.character(mitab$Potencia[1]), opiniones_texto, precio_texto)
:
Me funcionó, pregunte a R con la función help pero no me quedo claro, ¿qué hace exactamente el comando "trimws", Javier?, te agradeceré tu orientación.
trimws quita los espacios en blanco al principio y al final de una cadena, lo que incluye tabulaciones y saltos de página.
¡Hola!
.
Platzi es lo maximo
Y como todo lo bueno en la vida se necesita acompañar siempre con algo bueno tambien
Este curso esta genial, no hay la menor duda, pero ver este material complementado con otro material sea un libro, tutoriales en YouTube, articulos relacionados potencian cada conocimiento obtenido aqui
Saludos
.
Nota 1: el libro que empece hoy fue "Learn R Programming in 1 Day: Complete Guide for Beginners" de Krishna Rungta
.
Nota 2: en YouTube en el canal "Data Science Dojo" hay tutoriales con mas ejemplos de web scrapping. La narracion es fantastica
Un detalle no se si a los demas les pase pero mientras estoy viendo el video la barra de tiempo de reproducción no me deja ver el contenido, si bien cuando pasa un tiempo desparece en ocasiones es molesto pues uno necesita estar regresando y prestando atención a partes especificas del video. si se pudiera poner esa barra en una parte externa del video seria excelente
Hola, me esta repitiendo todos los datos
Comparto mi código, por si es de utilidad para alguien:
tabla <- "#prodDetails > div > div.column.col1 > div > div.content.pdClearfix > div > div > table"
tabla_nodo <- html_node(pagina_web, tabla)
if(!is.na(tabla_nodo)) {
tabla_especificaciones <- html_table(tabla_nodo)
tabla_especificaciones
class(tabla_especificaciones)
val <- tabla_especificaciones$X2
val
resultado_tabla <- data.frame(t(val))
resultado_tabla
tabla_name <- tabla_especificaciones$X1
tabla_name
colnames(resultado_tabla) <- tabla_name
resultado_tabla
}
col <- c("Peso del producto", "Dimensiones del paquete")
if(length(resultado_tabla)==0) {
# No hay detalles todo a -1
mi_tab <- data.frame(colnames(col))
mi_tab <- rbind(mi_tab, c("-1", "-1"))
colnames(mi_tab) <- col
} else {
# Evaluar cada atributo
zero <- matrix("-1", ncol = 4, nrow = 1)
dfzero <- as.data.frame(zero)
colnames(dfzero) <- col
peso <- as.character(resultado_tabla$Peso del producto)
if(length(peso)==0) peso <- "-1"
dim <- as.character(resultado_tabla$Dimensiones del paquete)
if(length(dim)==0) dim <- "-1"
dfzero$Peso del producto <- peso
dfzero$Dimensiones del paquete <- dim
mi_tab <- dfzero
colnames(mi_tab) <- col
}
articulo <- c(nombre_texto, precio_texto, opiniones_texto, as.character(mi_tab$Peso del producto[1]), as.character(mi_tab$Dimensiones del paquete[1]))
articulo
}
Buenas tardes. el resultado de mi tabla es algo diferente ya que elegí una aspiradora que no tenia los datos de la profe. Sin embargo, vi que los selectores de precios ourprice, saleprice y dealprice. Así que los puse en la tabla. Coloco mi código.
getItem<-function(url){ pws<-read_html(url) name<-"#productTitle" nd<-html_node(pws, name) ntxt<-html_text(nd) ntxt
opi<-"#acrCustomerReviewText" opind<-html_node(pws,opi) opintx<-html_text(opind) opintx
stars<-"#acrPopover > span.a-declarative > a > i.a-icon.a-icon-star.a-star-3-5 > span" starsnd<-html_node(pws,stars) starstx<-html_text(starsnd) starstx
price<-"#priceblock_ourprice" prind<-html_node(pws,price) printx<-html_text(prind) printx
priceS<-"#priceblock_saleprice" prindS<-html_node(pws,priceS) prinStx<-html_text(prindS) prinStx
priceDEAL<-"#priceblock_dealprice" prindD<-html_node(pws,priceDEAL) printxD<-html_text(prindD) printxD
table<-"#prodDetails > div > div.column.col1 > div > div.content.pdClearfix > div > div > table" tabnd<-html_node(pws,table)if(!is.na(tabnd)){ techtab<-html_table(tabnd) techtab
class(techtab) rval2<-data.frame(t(techtab$X2))colnames(rval2)<-techtab$X1 rval2
Resvac<-c(opintx,ntxt,printx,prinStx,printxD,starstx,as.character(rval2$Marca),as.character(rval2$`Peso del producto`),as.character(rval2$`Dimensiones del paquete`))Resvac} cn<-c("Marca","Peso del producto","Dimensiones del paquete")if(length(rval2)==0){ #No data
Mdf<-data.frame(colnames(cn))Mdf<-rbind(Mdf,c("-1","-1","-1"))colnames(Mdf)<-cn
}else{ #Evaluating attributes
Zero<-matrix("-1",ncol=3,nrow=1) dfzeros<-as.data.frame(Zero)colnames(dfzeros)<-cn
dfzeros
Marca<-as.character(rval2$Marca)if(length(Marca)==0)Marca<-"-1"Peso<-as.character(rval2$`Peso del producto`)if(length(Peso)==0)Peso<-"-1"Dimensiones<-as.character(rval2$`Dimensiones del paquete`)if(length(Dimensiones)==0)Dimensiones<-"-1" dfzeros$Marca<-Marca dfzeros$`Peso del producto`<-Peso dfzeros$`Dimensiones del paquete`<-DimensionesMdf<-dfzeros
colnames(Mdf)<-cn
}Item<-c(ntxt,as.character(Mdf$Marca),opintx,starstx,printx,prinStx,printxD,as.character(Mdf$`Peso del producto`),as.character(Mdf$`Dimensiones del paquete`))Item}getItem
RvOne<-sapply(Vlinksvacc,getItem)RvOneFdf1<-t(RvOne)Fdf2<-data.frame(Fdf1)Fdf2[,1]<-rownames(Fdf2)Fdf3<-Fdf2;rownames(Fdf3)<-NULLView(Fdf3)dim(Fdf3)colnames(Fdf3)<-c("url","Marca","Opiniones","Estrellas","Precio normal","Precio estandar","Precio oferta","Peso del Producto","Dimensiones del producto")rownames(Fdf3)<-c(1:180)View(Fdf3)
por alguna razon no esta leyendo mi url
Aiuuudaa :(
Porque al cerrar la sesion en Rscript y al abrir de nuevo y ejecutar las funciones, ya no me carga la url de la pagina de los articulo?
¡Hola @sabs_07! Lo más probable es que la url haya cambiado, o el contenido inclusive, por lo que la misma no funcionará si no cambias de url o el contenido de tus funciones ;)
Tengo un problema con los nombres lo que sucede es que al parecer a jalo los nombres de los productos junto con varias etiquetas de espaciado saben si hay forma de eliminarlos Gracias de antemano
Al momento de querer usar uno de mis link de mi banco de links de 200 que es de clase :charcter ; me sale un error de : does not exist in current working directory. Como puedo solucionar esto ?
A mi adicional de el problema de que no había una tabla en alguna url, me apareció este error:
me dirigi a la url y note que en vez de decir Dimensión del producto dice Dimensión del paquete, no se si se deba a eso y si es así como deba corregir el error, porque no se porque me evito correrlo todo.
Hola tuve un problema con Rstudio y nose solucionarlo. Sucede que cuando cargo el código por primera vez me funciona, pero despues de un tiempo, como que no me toma los selectores, en este caso del precio, opiniones y nombre, me los devuelve como NA. Si alguien sabe como solucionarlo le agradeceria.
Me paso lo mismo
Finalmente lo dejé así
###########################################
# Librerías de la rutina
library(xml2)library(rvest)library(stringr)
###########################################
# Ruta real de la pagina para webscraping
urlBase <-"https://www.amazon.com"url <-"https://www.amazon.com/s?k=aspiradoras&__mk_es_US=%C3%85M%C3%85%C5%BD%C3%95%C3%91&ref=nb_sb_noss_2"UrlPaginacion<-"https://www.amazon.com/-/es/s?k=aspiradoras&page=2&language=es_US&__mk_es_US=%C3%85M%C3%85%C5%BD%C3%95%C3%91&qid=1578546672&ref=sr_pg_2"paginacion <-1:10
###########################################
# Llamar función xml2 para creación del objeto tipo Htmlpagina_web <-read_html(url)nodo<-html_node(pagina_web,"div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div:nth-child(2) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > h2:nth-child(1) > a:nth-child(1)")nodo_Links <-html_attr(nodo,"href")pag <-str_replace(UrlPaginacion,"page=2",paste0("page=",paginacion))pag <-str_replace(pag,"sr_pg_2",paste0("sr_pg_",paginacion))obtenerLinksPaginacion <-function(url){ pagina_web <-read_html(url) nodo<-html_nodes(pagina_web,"div > div:nth-child(1) > div > div > div:nth-child(1) > h2 > a") nodo_Links <-paste0(urlBase,html_attr(nodo,"href")) nodo_Links
}test <-as.vector(sapply(pag,obtenerLinksPaginacion))url <- test[1]pagina_web <-read_html(url)nombre<-trimws(html_text(html_node(pagina_web,"#productTitle")))opiniones<-trimws(html_text(html_node(pagina_web,"#averageCustomerReviews_feature_div > div:nth-child(2) > span:nth-child(3) > a:nth-child(1) > span:nth-child(1)")))precio <-trimws(html_text(html_node(pagina_web,"#priceblock_ourprice")))detallesTecnicosTmp <-html_table(html_node(pagina_web,"#productDetails_detailBullets_sections1"))detalleTecnico <- data.frame(t(detallesTecnicosTmp$X2))colnames(detalleTecnico)<-detallesTecnicosTmp$X1listaAspiradoras <-c(nombre,precio,opiniones,as.character(detalleTecnico$`Peso del producto`),as.character(detalleTecnico$`Dimensiones del producto`,as.character(detalleTecnico$Fabricante)))getArticulo <-function(url){ pagina_web <-read_html(url) nombre<-trimws(html_text(html_node(pagina_web,"#productTitle"))) opiniones<-trimws(html_text(html_node(pagina_web,"#averageCustomerReviews_feature_div > div:nth-child(2) > span:nth-child(3) > a:nth-child(1) > span:nth-child(1)"))) precio <-trimws(html_text(html_node(pagina_web,"#priceblock_ourprice"))) nodoDetalleTecnico <-html_node(pagina_web,"#productDetails_detailBullets_sections1")if(!is.na(nodoDetalleTecnico)){ # Validar valor de los nodos de la tabla
detallesTecnicosTmp <-html_table(nodoDetalleTecnico) detalleTecnico <- data.frame(t(detallesTecnicosTmp$X2))} col<-c("Peso del producto","Dimensiones del producto","Fabricante","Potencia")if(length(detalleTecnico)==0){ # No encuentra datos
frameAspiradoras <- data.frame(colnames(col)) frameAspiradoras <-rbind(frameAspiradoras,c("-1","-1","-1","-1"))colnames(frameAspiradoras)<- col
}else{ # Evaluar cada atributo
zero <-matrix("-1",ncol =4, nrow =1) dfzero <-as.data.frame(zero)colnames(dfzero)<- col
PesoTb<-as.character(detalleTecnico$`Peso del producto`)DimensionesTb<-as.character(detalleTecnico$`Dimensiones del producto`)FabricanteTb<-as.character(detalleTecnico$Fabricante)PotenciaTb<-as.character(detalleTecnico$Potencia)if(length(PesoTb)==0)PesoTb="-1"if(length(DimensionesTb)==0)DimensionesTb="-1"if(length(FabricanteTb)==0)FabricanteTb="-1"if(length(PotenciaTb)==0)PotenciaTb="-1" dfzero$`Peso del producto`<-PesoTb dfzero$`Dimensiones del producto`<-DimensionesTb dfzero$Fabricante <-FabricanteTb dfzero$Potencia <-PotenciaTb frameAspiradoras <- dfzero
colnames(frameAspiradoras)<- col
} articulo <-c(nombre, opiniones, precio,as.character(frameAspiradoras$`Peso del producto`[1]),as.character(frameAspiradoras$`Dimensiones del producto`[1]),as.character(frameAspiradoras$Fabricante[1]),as.character(frameAspiradoras$Potencia[1]))
articulo
}articulos <-sapply(test,getArticulo)matrixArticulos <-t(articulos)dataFrameArticulos <- data.frame(matrixArticulos)colnames(matrixArticulos)<-c("Nombre","Califiaciones","Precio","Peso","Dimensiones","Fabricante","Potencia")rownames(matrixArticulos)<-c(1:220)
Me aparece como problema que no es una pagina activa del sitio.
getArticulo<-function(url){print(url) nombre<-"#productTitle" pagina_web<-read_html(url) nombre_nodo<-html_node(pagina_web,nombre) nombre_texto<-html_text(nombre_nodo) opiniones<-"#acrCustomerReviewText" opiniones_nodo<-html_node(pagina_web,opiniones) opiniones_texto<-html_text(opiniones_nodo) precio<-"#priceblock_ourprice" precio_nodo<-html_node(pagina_web,precio) precio_texto<-html_text(precio_nodo) tabla<-"#prodDetails > div.wrapper.ESlocale> div.column.col1> div:nth-child(1)> div.content.pdClearfix> div > div > table" tabla_nodo<-html_node(pagina_web,tabla)if(!is.na(tabla_nodo)){ tabla_tab<-html_table(tabla_nodo)class(tabla_tab) val<-tabla_tab$X2 res_tabla<-data.frame(t(val)) tabla_name<-tabla_tab$X1colnames(res_tabla)<-tabla_name
res_tabla
} col<-c("Peso del producto","Dimensiones del producto","Volumen","Potencia")if(length(res_tabla)==0){ #no hay detalles todo a-1 mitab<-data.frame(colnames(col)) mitab<-rbind(mitab,c("-1","-1","-1","-1"))colnames(mitab)<-col
}else{ #Evaluar cada uno de los atributos
zero<-matrix("-1",ncol=4,nrow=1) dfzero<-as.data.frame(zero)colnames(dfzero)<-col
peso<-as.character(res_tabla$`Peso del producto`)if(length(peso)==0)peso<-"-1" dim<-as.character(res_tabla$`Dimensiones del producto`)if(length(dim)==0)dim<-"-1" potencia<-as.character(res_tabla$`Potencia`)if(length(potencia)==0)potencia<-"-1" volumen<-as.character(res_tabla$`Volumen`)if(length(volumen)==0)volumen<-"-1" dfzero$`Peso del producto`<-peso
dfzero$`Dimensiones del producto`<-dim
dfzero$Volumen<-volumen
dfzero$Potencia<-potencia
mitab<-dfzero
colnames(mitab)<-col
} articulo<-c(nombre_texto, precio_texto,opiniones_texto,as.character(mitab$`Peso del producto`[1]),as.character(mitab$`Dimensiones del producto`),as.character(mitab$Volumen),as.character(mitab$Potencia)) articulo
}r<-getArticulo(vlinkAspiradora[321])resultado_datos<-sapply(vlinkAspiradora,getArticulo)res<-t(resultado_datos)View(res)mis_aspiradoras<-as.data.frame(res)colnames(res)<-c("Nombre","Precio","Opiniones","Peso del producto","Dimensiones del producto","Volumen","Potencia")rownames(res)<-c(1:200)View(res)```
interesante!
Tengo un problema, sucede que la Variable Resultado Datos me esta arrojando un Class tipo List más no un Tipo Matriz... ya revise todo el codigo y no comprendo que puede estar ocurriendo. ¿Alguien sabe porque ocurre esto?
tienes que transformar esa lista en matrix, solo debes poner esta linea de código