Post

python 뮤직 차트 데이터 가져오기

Pytho, 크롤링

자신이 원하는 데이터를 웹사이트에서 가져오는 걸 크롤링이라고 합니다.
오늘은 Python을 사용하여 소리바다 사이트에서 뮤직차트 데이터를 저장해보겠습니다.

준비물

당연히 python이 필요하고 크롤링을 위한 package도 몇 가지 설치해야 합니다.

  1. selenium : 웹 애플리케이션을 자동으로 테스트하고 브라우저를 제어하는 데 사용됩니다.
  2. pandas : 소리바다 인기차트 데이터를 json파일로 저장할 떄 사용할 패키지입니다.
  3. webdriver_manager : 크롬, 엣지 등 웹 브라우저를 제어하기 위한 패키지.

위 3개의 패키지는 필수로 설치해주셔야 합니다.

헤더 설정.

크롤링을 진행할 때 헤더라는 것을 설정하지 않으면
접속하려는 사이트에서 차단을 시키는 경우가 있습니다.
이걸 방지하기 위해 설정하는 것이 헤더입니다.

먼저 전체 패키지 import부분부터 살펴보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
import time # 페이지 접속후 안전성을 위해 잠시 대기할 때 사용.
from selenium import webdriver # 웹 브라우저 설정.
from selenium.webdriver.common.by import By 
# 웹 페이지의 태그, 클래스 명을 선택할 때 사용
from selenium.webdriver.chrome.service import Service as ChromeService
# 크롬 웹 브라우저를 사용할 예정으로 크롬 웹 드라이버를 설치하기 위해 선언.
from selenium.webdriver.chrome.options import Options as ChromeOptions
# 크롬 웹 브라우저 헤더 설정을 위해 선언.
from webdriver_manager.chrome import ChromeDriverManager
# 크롬 웹 드라이버 설치
import pandas as pd
# json 파일 설정, 생성.

패키지 별로 무엇을 위해 선언했는지 작성해두었으니 참고 바랍니다.
이제 헤더를 설정해보겠습니다.

1
2
3
4
5
6
# Chrome 옵션 설정
options = ChromeOptions()
options.add_argument("window-size=1920x1080")
options.add_argument("disable-gpu")
options.add_argument("lang=ko_KR")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64")

options라는 변수를 통해 chrome 브라우저의 알맞는 헤더를 설정해줍니다.

options.add_argument("window-size=1920x1080")를 작성하게 되면 코드를 실행할 때
크롬 브라우저가 실행되어 진행상황을 직접 볼 수 있습니다.

1
2
3
options.add_argument("disable-gpu")
options.add_argument("lang=ko_KR")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64")

그외 나머지 코드들은 우리가 접속하려는 사이트에게 봇이 아니라는 걸 증명하기 위해 사용되는 코드이다.
정도로만 알고 계시면 될 것 같습니다.

이제 소리바다 사이트에 접속할 차레인데, 그전에 코드의 진행 순서를 한 번 정리하자면,

  1. 소리바다 뮤직차트 접속
  2. 뮤직 차트 데이터 복사
  3. 필요한 데이터 정리 : 순위, 제목, 가수
  4. json 파일로 생성.

이렇게 진행할 예정입니다.
소리바다 뮤직 차트에 접속해보겠습니다.

1
2
3
4
5
service = ChromeService(executable_path=ChromeDriverManager().install()) 
driver = webdriver.Chrome(service=service, options=options)

driver.get('https://www.soribada.com/music/chart')

이렇게 코드를 작성하고서 실행을 해보신다면,
크롬 브라우저가 실행되어 소리바다 뮤직 차트에 접속하는 걸 확인하실 수 있습니다.
코드에 대해 설명하자면.

1
2
service = ChromeService(executable_path=ChromeDriverManager().install()) 
driver = webdriver.Chrome(service=service, options=options)

service라는 변수를 선언하여 크롬에서 제공하는 크롬 웹 드라이버를 코드에서 설치하여
인식할 수 있도록 해줍니다.
여기서 웹드라이버는 크롬이나 엣지와 같은 브라우저들을 우리가 작성한 코드에서
제어할 수 있도록 만들어주는 프로그램의 일종이라고 생각하시면 됩니다,

driver 변수는 앞에서 만들어둔 변수를 통해 실행될 크롤러 입니다.
헤더options와 웹 드라이버 정보가 담긴 servie를 통해 웹 사이트에 접속합니다.

driver.get('https://www.soribada.com/music/chart')에서
.get() 이라는 메소드는 설정한 url에 접속하는 메소드입니다.
여기까지가 위에서 정리한 진행 순서 중 1번, 소리바다 뮤직차트 접속이자,
헤더설정이었습니다.

크롤링

이제 본격적으로 소리바다 사이트에서 뮤직차트를 만들 때 필요한,
순위, 노래 제목, 가수 정보를 가지고 오겠습니다.
먼저 코드를 살펴보면.

1
2
3
time.sleep(2)

search_box = driver.find_element(By.CLASS_NAME, 'music-list')

코드 자체는 생각보다 간결합니다.
먼저 프로그램의 안정성을 위해 페이지 접속 후,
time.sleep(2)를 작성하여 페이지 로드 후 2초 동안 대기합니다.

그런 후 search_box라는 변수안에 우리의 크롤러, driver의 데이터 중,
music-list 즉, 소리바다 사이트의 전체 코드 중, music-list라는 클래스 명을 가진 요소를 찾아냅니다.

여기서 .find_element를 통해 곧바로 순위나 노래 제목을 찾지 않은 이유는
왜인지는 모르겠지만 소리바다 사이트에서 바로 순위나 노래제목을 찾으면
정상적으로 크롤링이 되지 않았기 떄문입니다.
그래서 먼저 뮤직차트의 전체 소스를 가져온 뒤 순위,제목,가수를 찾을 겁니다.

이제 search_box에서 우리에게 필요한 데이터들을 찾아보겠습니다.

1
2
3
4
5
6
7
rankings = search_box.find_elements(By.CLASS_NAME , 'num')
titles = search_box.find_elements(By.CLASS_NAME , 'song-title')
artist = search_box.find_elements(By.CLASS_NAME ,  'link-type2-name')

rankList = [rank.text for rank in rankings]
titleList = [title.text for title in titles]
artistList = [art.find_element(By.TAG_NAME , 'span').text for art in artist]

언뜻보면 복잡해보이지만, 하나씩 살펴보면 정말 간단한 코드입니다.
먼저 소리바다 사이트에서 순위를 담고있는 요소의 클래스 명은 num으로 설정이 되어있습니다.

1
rankings = search_box.find_elements(By.CLASS_NAME , 'num')

search_box에서 다시 한 번 num이라는 클래스 명을 가진 요소를 찾은 후,
rankings라는 변수에 저장했습니다.

그러나 지금 rankings의 변수 안에는 우리가 원하는 데이터 형식인,
1,2,3,4… 이런 식으로 저장이 되어있는 게 아닌,
selenium의 자체 방식으로 저장이 되어있습니다.
이를 해결하기 위해
rankList = [rank.text for rank in rankings]이렇게 작성했습니다.


for문과 .text 를 사용해 rankList에 우리에게 필요한 데이터,
1,2,3,4… 순위를 저장했습니다.

나머지 제목과 가수도 동일한 방식입니다.
필요한 데이터는 모두 저장했으니, json파일로 저장해보겠습니다.

json 파일로 저장하기.

이제 pands 패키지를 사용하여 데이터 프레임을 설정하고,
json파일을 생성하면 끝입니다.

코드를 살펴보겠습니다.

1
2
3
4
5
6
7
8
chart_df = pd.DataFrame({
    "Ranking" : rankList,
    "Title" : titleList , 
    "Artist" : artistList
})


chart_df.to_json("soriBadaMusicChart.json", force_ascii=False , orient="records")

chart_df는 데이터 프레임 변수입니다.
설정한 데이터 프레임을 .to_json()메소드를 통해 json파일의 제목과
필요 옵션들을 설정해주면 json파일이 생성됩니다.

최종 정리용으로 전체 코드를 작성해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options as ChromeOptions
from webdriver_manager.chrome import ChromeDriverManager
import pandas as pd

import json
from collections import OrderedDict

# Chrome 옵션 설정
options = ChromeOptions()
options.add_argument("window-size=1920x1080")
options.add_argument("disable-gpu")
options.add_argument("lang=ko_KR")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36")
service = ChromeService(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)



# 사이트 접속
driver.get('https://www.soribada.com/music/chart')


time.sleep(2) 

search_box = driver.find_element(By.CLASS_NAME, 'music-list')

rankings = search_box.find_elements(By.CLASS_NAME , 'num')
titles = search_box.find_elements(By.CLASS_NAME , 'song-title')
artist = search_box.find_elements(By.CLASS_NAME ,  'link-type2-name')

rankList = [rank.text for rank in rankings]
titleList = [title.text for title in titles]
artistList = [art.find_element(By.TAG_NAME , 'span').text for art in artist]


# 데이터 프레임 생성
chart_df = pd.DataFrame({
    "Ranking" : rankList,
    "Title" : titleList , 
    "Artist" : artistList
})


chart_df.to_json("soriBadaMusicChart.json", force_ascii=False , orient="records")

생각보다 간단하게 크롤링 할 수 있었습니다.
오늘은 저도 처음해보는 크롤링에 대해 정리를 해보았는데,
많이 부족하지만 필요한 분들에게 도움이 됬으면 합니다.

This post is licensed under CC BY 4.0 by the author.