Motivación

La pagina Letras.Com tiene las letras de las canciones de muchisimos artistas.

Construi una función que permite descargar las letras de todas las canciones (o solo algunas) del artista que más nos guste.

Ejemplo de Uso

Respuesta

Estructura

Se trata de una lista con dos elementos: Resumen y Letras.

str(Resultados)
## List of 2
##  $ Resumen:'data.frame': 280 obs. of  2 variables:
##   ..$ nombre: chr [1:280] "Otherside" "Californication" "Dani California" "Dark Necessities" ...
##   ..$ pag   : chr [1:280] "https://www.letras.com/red-hot-chili-peppers/1965384/" "https://www.letras.com/red-hot-chili-peppers/32764/" "https://www.letras.com/red-hot-chili-peppers/529158/" "https://www.letras.com/red-hot-chili-peppers/dark-necessities/" ...
##   ..- attr(*, ".internal.selfref")=<externalptr> 
##  $ Letras :List of 5
##   ..$ Otherside       : chr "How long, how long will I slide?\nSeparate my side, I don’t\nI don’t believe it’s bad\nA slit in my throat, it’"| __truncated__
##   ..$ Californication : chr "Psychic spies from China\nTry to steal your mind's elation\nLittle girls from Sweden\nDream of silver screen qu"| __truncated__
##   ..$ Dani California : chr "Getting born in the State of Mississippi\nPapa was a copper\nAnd mama was a hippie\nIn Alabama\nShe would swing"| __truncated__
##   ..$ Dark Necessities: chr "Coming on to the light of day, we got\nMany moons that are deep at play, so I\nKeep an eye on the shadow smile\"| __truncated__
##   ..$ Can&#39;t Stop  : chr "Can't stop, addicted to the shin dig\nChop Top, he says I'm gonna win big\nChoose not a life of imitation\nDist"| __truncated__

Resumen

Tabla de resumen con los nombres y los links a la pagina Letras.com

DT::datatable(Resultados$Resumen,rownames = FALSE)

Letras

Ejemplo del primer elemento del bloque Letras (El bloque es una lista)

cat(Resultados$Letras$Otherside)
## How long, how long will I slide?
## Separate my side, I don’t
## I don’t believe it’s bad
## A slit in my throat, it’s all I ever
## I heard your voice through a photograph
## I thought it up and brought up the past
## Once you know you can never go back
## I’ve got to take it on the otherside
## Centuries are what it meant to me
## A cemetery where I marry the sea
## Stranger things could never change my mind
## I’ve got to take it on the otherside
## Take it on the otherside
## Take it on
## Take it on
## How long, how long will I slide?
## Separate my side, I don’t
## I don’t believe it’s bad
## A slit in my throat, it’s all I ever
## Pour my life into a paper cup
## The ashtray’s full and I’m spillin’ my guts
## She wants to know am I still a slut
## I’ve got to take it on the otherside
## Scarlet starlet and she’s in my bed
## A candidate for my soul mate bled
## Push the trigger and I pull the thread
## I’ve got to take it on the otherside
## Take it on the otherside
## Take it on
## Take it on
## How long, how long will I slide?
## Separate my side, I don’t
## I don’t believe it’s bad
## A slit in my throat, it’s all I ever
## Turn me on, take me for a hard ride
## Burn me out, leave me on the otherside
## I yell and tell it that it’s not my friend
## I tear it down, I tear it down and then it’s born again
## How long, how long will I slide?
## Separate my side, I don’t
## I don’t believe it’s bad
## A slit in my throat it’s all I ever had
## (How long?)
## I don't, I don’t believe it’s bad
## A slit in my throat, it’s all I ever

Código

DESCARGAR_LETRAS<-function(pagina,limite=NULL) {

  suppressWarnings({
  
  require(stringr)
  require(data.table)
  require(dplyr)
  
 
a<-readLines(pagina
             ,encoding = "UTF-8")

which(str_detect(a,"data-name"))[2]->cual

str_split(a[cual],"<li class")[[1]]->s

  listado<-list()
  for (j in 1:length(s)) {
  
    x<-s[j]
    
    rdo_1<-str_split(unlist(str_split(unlist(str_split(x,"data-name=")),
                                    " data-shareurl="))," data-sharetext=")
  
    if (length(unlist(rdo_1))==4) {
    a1<-data.table(
      nombre=str_remove_all(rdo_1[[2]],'\"'),
      pag=str_remove_all(rdo_1[[3]][1],'\"')
    )
    } else {
    a1<-data.table(
      nombre="",
      pag=""
    )
    }

    listado[[j]]<-a1
}

rbindlist(listado) %>%
  filter(nombre!="")->d

if (limite==0) {
  cuanto<- nrow(d)
} else {cuanto<-min(c(limite,nrow(d)))}
 
 
letras<-list()
pb = txtProgressBar(min = 0, max = cuanto, initial = 0) 
for (i in 1:cuanto)  {

d$pag[i]->direccion  
setTxtProgressBar(pb,i)

texto<-readLines(direccion,encoding = "UTF-8")

which(str_detect(texto,"<p>"))[1]->cual2
str_split(texto[cual2],"<p>")[[1]]->k

#k2<-k[-c(1,length(k))]
k2<-k[-1]
k3<-str_replace_all(k2,"<br/>","\n")
k4<-str_remove_all(k3,"</p>")
k5<-paste(k4,collapse="\n")
k6<-str_split(k5,"</div>")[[1]][1]
k6<-str_replace_all(k6,"&#39;","'")
letras[[i]]<-k6
}

names(letras)<-d$nombre[1:cuanto]
})
return(list(Resumen=d,Letras=letras))
}

Descargar_Artista<-function(buscado) {
  
  suppressWarnings({
  require(stringr)
  require(data.table)
  require(dplyr)
  
  pb2 = txtProgressBar(min = 0, max = length(LETTERS), initial = 0) 
  listado_artistas<-list()
  
  for (i in LETTERS) {
    
    setTxtProgressBar(pb2,which(LETTERS==i))
    readLines(paste("https://www.letras.com/letra/",i,"/",sep=""),
              encoding = "UTF-8")->a
    
    which(str_detect(a,"<b>"))[1]->cual3
    a[cual3]->a
    str_split(a,"<li>")[[1]]->a2
    
    x<-a2[2]
    
    lapply(a2,function(x) {
      
      
      str_split(x,">")[[1]]->s
      
      if (length(s)==11) {
        
        pag<-paste("https://www.letras.com/",
                   str_split(s[1],'"')[[1]][2],
                   "/mais_tocadas.html",sep="")
        
        recorte<-str_split(x,"b>")[[1]][2]
        artista<-substr(recorte,1,nchar(recorte)-2)
        
        datos<-data.table(artista=artista,pag=pag)
        
      } else {
        
        datos<-data.table(artista="",pag="")
        
      }
      
      return(datos)
    })->listado
    
    artistas<-rbindlist(listado) %>% filter(artista!="")
    
    listado_artistas[[length(listado_artistas)+1]]<-artistas
  }
  
  
  listado_artistas<-rbindlist(listado_artistas)
  
  listado_artistas %>%
    filter(str_detect(tolower(artista),buscado)) %>%
    as.data.frame()->opciones
  
  posibles<-opciones$artista
  seleccion<-menu(posibles,"Elegir el Artista")
  
  limitee<-c(0,1,5,10,50,100)[menu(c("Todas las Canciones","Primera",
                                    "Primeras 5","Primeras 10",
                                    "Primeras 50","Primeras 100"))]
  print(limitee)
  
  DESCARGAR_LETRAS(opciones$pag[seleccion],limitee)->k
  })
  return(k)
}