2020년과 프로젝트 시작 : Spotify Web Scraping in R

Dahee Lee
13 min readJan 8, 2020

--

Photo by Alesia Kazantceva on Unsplash

2020년을 새롭게 시작하기 위해서 2019년 12월 말부터 시작하게 된 개인 프로젝트에 대한 기록을 해보고자 한다. #newyearnewme

프로젝트를 시작한 이유

2020년 4월 드디어 Coachella Music Festival에 간다.

무슨 상관?

20살 뮤직 페스티벌에 빠지기 시작했을 때 부터 20대에 꼭 Coachella Music Festival에 가겠다! 고 다짐을 했었는데 정말 딱 29살에 간!다!

Photo by Andrew Ruiz on Unsplash

2019년 12월.

티켓은 사놓았지만 라인업은 아직 공개가 되지 않은 시점이었다.

(아직도 TMI)

한두푼 하는 티켓 값도 아닐 뿐더러 무작정 티켓은 샀지만 그래도 라인업은 너무 너무 궁금하니까 역대 라인업을 쭉 보다가

흠.. 내가 예측할 수 있지 않을까?하는 생각이 들었다.

어떻게?

Spotify의 스트리밍 데이터를 이용해보기로 했다.

Coachella Music Festival은 미국에서 열리는 행사이고 미국에서 가장 많은 이용자 수를 갖고 있는 음악 스트리밍 앱은 Spotify이고 아티스트의 스트리밍 데이터를 분석해보면 라인업을 알 수 있을 것만 같았다.

데이터는?

Spotify Chart TOP 200에 대한 각 국가별, 날짜별 스트리밍을 확인할 수 있는 웹사이트가 있다.

아래 이미지처럼 필터에 따라서 국가별, 날짜별 데이터를 CSV 파일로 다운로드 받을 수 있는데

흠…

2020년 1월 6일 글로벌 TOP 200의 스트리밍만 궁금하다면 바로 해당 국가, 해당 일자의 데이터를 CSV로 받으면 되겠지만 나는 미국의 총 3개년(2017–2019) 데이터 전체가 필요했고 일일이 필터를 바꿔가며1095번(365*3) DOWNLAD TO CSV를 누르고 싶지 않았다.

그럼 진짜 어떻게?

웹 스크래핑을 해보기로 했다.

예전에 R을 이용해 멜론 웹 스크래핑 했을 때의 기억을 더듬어서 진행해보았다.

Spotify Web Scraping

1. 리서치

일단 나와 같은 경우가 많겠지 싶어서 예시를 찾기 위해 열심히 구글링을 시작했다. 당연히 있다. 아래 링크는 RPubs에 있는것으로 데이터 스크랩부터 시각화까지에 해당하는 내용이다. 먼저 이 링크에서 전반적인 내용을 훑어보았다.

라이브러리

필요한 라이브러리는 아래와 같다.

rvest

tidyverse

magrittr

URL 구조

spotifycharts.com 의 URL은 국가별, 날짜별 필터에 따라 CountryCode, YYYY-MM-DD 부분이 바뀐다.

https://spotifycharts.com/regional/CountryCode/daily/YYYY-MM-DD

예를 들어

2020년 1월 6일 영국의 URL https://spotifycharts.com/regional/gb/daily/2020-01-06

2020년 1월 7일 미국의 URL https://spotifycharts.com/regional/us/daily/2020-01-07

하지만 RPubs 링크의 글은 url이 이미 아래와 같이 us로 고정되어 시작한다. 즉, 미국의 날짜별 스트리밍 데이터를 스크랩 하는 코드이다.

url <- "https://spotifycharts.com/regional/us/daily/"

하지만 나는 이왕하는거 + 분석의 확장을 위하여 국가별, 날짜별 필터까지 적용된 코드를 직접 짜보기로 했다.

2. 코딩

  1. 필요한 패키지를 로딩한다.
library(rvest)
library(tidyverse)
library(magrittr)

2. URL에 들어갈 국가와 날짜를 각각 countries, timevalues 변수에 넣는다.

countries : 국가는 총 65개국

timevalues : 날짜는 2017–01–01 부터 2019-12-31일 까지이다.

countries <- c(‘global’,’us’,’gb’,”ar”,”at”,”au”,”be”,”bg”,”bo”,”br”,”ca”,”ch”,”cl”,”co”,”cr”,”cy”,”cz”,”de”,“dk”,”do”,”ec”,”ee”,”es”,”fi”,”fr”,”gr”,”gt”,”hk”,”hn”,”hu”,”id”,”ie”,”il”,”in”,”is”,”it”,”jp”,“lt”,”lu”,”lv”,”mc”,”mt”,”mx”,”my”,”ni”,”nl”,”no”,”nz”,”pa”,”pe”,”ph”,”pl”,”pt”,”py”,”ro”,”se”,“sg”,”sk”,”sv”,”th”,”tr”,”tw”,”uy”,”vn”,”za”)timevalues <- 
seq(as.Date("2017/01/01"), as.Date("2019/12/31") , by = "day")

3. 필요한 Vector, Data Frame를 만든다.

url_2 : 국가 코드까지 들어간 URL을 담을 Vector

full_url : 국가 코드와 날짜까지 들어간 URL을 담을 Vector

spotify_scrapped : URL별로 스크랩된 데이터를 담을 Data Frame

url_2 <- vector( mode = ‘character’,length(countries))full_url <- vector( mode = ‘character’,length(timevalues) * length(countries))spotify_scrapped <- data.frame(“Rank”, “Track”, “Artist”, “Streams”,”Country”, “Date”,”URL”)names(spotify_scrapped) <- c(“Rank”, “Track”, “Artist”, “Streams”,”Country”, “Date”,”URL”)spotify_scrapped <- spotify_scrapped[-1,]

4. URL에서 필요한 데이터를 스크랩하는 SpotifyScrape 함수를 만든다.

rank, track, artist, streams, country, dates, url에 대한 데이터를 가져오고

컬럼으로 묶은 후 Rank, Track, Artist, Streams, Country, Date, URL로 필드명을 지정한 뒤 tibble 형태의 chart 를 만든다.

SpotifyScrape <- function(x){  
page <- x
rank <- page %>% read_html() %>% html_nodes('.chart-table-position') %>% html_text() %>% as.data.frame()
track <- page %>% read_html() %>% html_nodes('strong') %>% html_text() %>% as.data.frame()
artist <- page %>% read_html() %>% html_nodes('.chart-table-track span') %>% html_text() %>% as.data.frame()
streams <- page %>% read_html() %>% html_nodes('td.chart-table-streams') %>% html_text() %>% as.data.frame()
country <- page %>% read_html() %>% html_node('.responsive-select-value') %>% html_text() %>% as.data.frame()
dates <- page %>% read_html() %>% html_nodes('.responsive-select~ .responsive-select+ .responsive-select .responsive-select-value') %>% html_text() %>% as.data.frame()
url <- page %>% read_html() %>% html_nodes('.chart-table-image') %>% html_nodes('a') %>% html_attr('href') %>% as.data.frame()
#combine, name, and make it a tibble
chart <- cbind(rank, track, artist, streams, country, dates, url)
names(chart) <- c("Rank", "Track", "Artist", "Streams","Country", "Date","URL")
chart <- as.tibble(chart)
return(chart) }

5. 웹 스크래핑을 시작한다.

이 부분에 대한 내용은 잘 찾아볼 수가 없어서 직접 코딩하느라 나름의 챌린지였고 제일 뿌듯한 부분이기도 하다 :)

for 반복문을 이용하여 url_2와 full_url을 만들고 위에서 만든 SpotifyScrape 함수에 full_url을 넣어 spotify에 데이터를 임시 저장하고 spotify_scrapped에 모든 데이터를 축적한다.

혹시 해당 국가, 해당 일자의 URL이 없을 경우는 tryCatch를 이용해 에러 메세지를 표시하고 다음 반복문으로 넘어간다.

for (i in 1: length(countries)) {
url_2[i] <- paste0 ("https://spotifycharts.com/regional/",countries[i],'/','daily','/')
#print(url_2[i])
for (j in 1: length(timevalues) ) {
full_url[j] <- paste0(url_2[i],timevalues[j])
#print(full_url[j])
tryCatch (
{spotify <- map_df(full_url[j] , SpotifyScrape)
spotify_scrapped <- rbind(spotify_scrapped, spotify)
if (j > length(timevalues) ) {
j = 1
} else {
j = j + 1
}
}, error = function(e) message(paste("URL does not seem to exist:", full_url[j]))
)
}
i = i + 1
}

4. 데이터 필터

분석의 확장을 위하여 모든 국가의 데이터를 스크랩 했지만 일단 미국의 데이터만 필요하니 Country가 United States인 행만 필터하여 spotify_scrapped_us에 저장한다.

spotify_scrapped_us <- filter(spotify_scrapped, Country == 'United States')

5. 데이터 확인

데이터를 확인해본다. 총 218200행이다.

view(spotify_scrapped_us)
dim(spotify_scrapped_us)
[1] 218200 7

6. 데이터 정제

위에 스크린샷을 보면 수정해야할 부분들이 있다.

Artist : by 지우기

Streams : 컴마 지우고 집계를 위해 문자형식을 숫자형식으로 바꾸기

Date : 연/월/일 트렌드를 보기 위해 문자형식을날짜형식으로 바꾸기

수정 후 테이블은 다시 한번 확인해본다.

spotify_scrapped_us %<>% mutate(Artist = gsub("by ", "", Artist),  Streams = gsub(",", "", Streams),  Streams = as.numeric(Streams),  Date = as.Date(spotify_scrapped_us$Date, "%m/%d/%Y"))view(spotify_scrapped_us)

7. 데이터 추출

정리가 다 되었으니 csv파일로 로컬에 추출한다.

write.csv(spotify_scrapped_us,'/Users/dahee/Desktop/Project_dahee/spotify/spotify_us.csv')

US의 3개년 Spotify Streaming 데이터 스크랩 완료!

Photo by Sergey Zolkin on Unsplash

다음 글에서는 아래 내용들에 대해 기록해보도록 하겠다.

Tableau를 활용한 데이터 시각화

Coachella 라인업 데이터 스크랩

Spotify Streaming 과 Coachella 라인업과의 상관 분석 및 예측 분석

그나저나 프로젝트를 진행하던 중에 2020년 1월 3일에 라인업이 발표가 났다. 예측해보려고 했으나 답지라고 생각하고 한번 풀어나가야겠다.

그나저나 라인업 대박 ㅠㅠ 4월까지 열심히 존버하며 기다려보아야지!

(혹시 궁금한 분들을 위해서 Coachella Music Festival를 준비하는 과정도 다뤄볼까 고민이다)

저의 커리어는 Linkedin 에서

데이터 시각화는 Tableau Public 에서

라이프스타일은 Instagram 에서 확인하실 수 있습니다:)

글과 관련하여 궁금한 점은 댓글 또는 daheelee1114@gmail.com 로 주세요!

--

--