본문 바로가기
프로그래밍💻/개인프로젝트

[python/파이썬] 멜론차트 크롤링

by 스닝 2022. 8. 10.

멜론 차트 크롤링

멀티캠퍼스 국비지원 '서비스 산업 데이터를 활용한 빅데이터 분석' 과정을 수강하며
첫 번째로 했던 프로젝트

# 2021년 12월 월간 top100 데이터 크롤링 후 선호 장르 조사

# 라이브러리 import
import sys
import os

import pandas as pd
import numpy as np 


from selenium import webdriver  
from selenium.webdriver import ActionChains as AC
import chromedriver_autoinstaller
from tqdm import tqdm
from tqdm import tqdm_notebook
import re
from time import sleep
import time

# 워닝 무시
import warnings
warnings.filterwarnings('ignore')
# 크롬 웹 브라우저 실행
chrome_path = chromedriver_autoinstaller.install()
driver = webdriver.Chrome(chrome_path)
#사이트 주소는 멜론
driver.get("https://www.melon.com/")
time.sleep(2)

 

차트 전체를 크롤링 하기 전 곡 하나 크롤링 테스트

#멜론차트 클릭
driver.find_element_by_css_selector(".menu_bg.menu01").click( )
time.sleep(1)
#월간차트 클릭
driver.find_element_by_css_selector(".menu_chart.m4").click( )
# 곡정보 더보기 버튼 클릭
more_info = driver.find_elements_by_css_selector(".btn.button_icons.type03.song_info")
more_info[0].click()
time.sleep(1)

 

곡 제목, 가수, 앨범 정보, 앨범 이름, 장르, 좋아요 수 수집

# 제목 가져오기
overlays1=".song_name"
titles = driver.find_elements_by_css_selector(overlays1)
titles[0].text

# 가수 가져오기
overlays2=".artist_name"
artist = driver.find_element_by_css_selector(overlays2)
artist.text

# 앨범 정보
overlays3=".list"
album_info = driver.find_element_by_css_selector(overlays3).text.split('\n')
album_info

# 앨범이름 
overlays3= ".list"
album_info = driver.find_element_by_css_selector(overlays3).text.split('\n')
album = album_info[1]
album

#장르
overlays3 = ".list"
album_info = driver.find_element_by_css_selector(overlays3).text.split('\n')
Genre = album_info[5]
Genre

# 좋아요 수
overlays4="d_like_count"
like = driver.find_element_by_id(overlays4)
like.text

# 뒤로가기
driver.back()

 

전체 멜론 차트 top 100 for문으로 데이터 수집

#멜론차트 클릭
driver.find_element_by_css_selector(".menu_bg.menu01").click( )
time.sleep(1)

#월간차트 클릭
driver.find_element_by_css_selector(".menu_chart.m4").click( )

dict={}

n=100

for i in tqdm_notebook(range(0,n)):

    #곡 정보 더보기
    more_info = driver.find_elements_by_css_selector(".btn.button_icons.type03.song_info")
    more_info[i].click()
    time.sleep(1)

    try:
        target_info={}

        # 제목 
        overlays=".song_name"
        titles = driver.find_element_by_css_selector(overlays)
        title=titles.text

        #가수
        overlays2=".artist_name"
        artists = driver.find_element_by_css_selector(overlays2)
        artist=artists.text


        # 앨범 정보
        overlays3=".list"
        album= driver.find_element_by_css_selector(overlays3).text.split('\n')
        album_info=album

        time.sleep(1)

        # 앨범이름 
        overlays3= ".list"
        album_info= driver.find_element_by_css_selector(overlays3).text.split('\n')
        album_name = album_info[1]

        #장르
        overlays3 = ".list"
        album_info= driver.find_element_by_css_selector(overlays3).text.split('\n')
        Genre = album_info[5]

        # 좋아요 수
        overlays4="d_like_count"
        likes = driver.find_element_by_id(overlays4)
        like=likes.text

        target_info['title'] = title
        target_info['artist'] = artist
        target_info['album_name'] = album_name
        target_info['Genre'] = Genre
        target_info['like'] = like
        time.sleep(1)

        #dict에 담기
        dict[i] = target_info

        #크롤링 성공하면 글 제목 출력
        print(i, title)

        #글 하나 크롤링 후 뒤로가기
        driver.back()

    #에러처리
    except:
        driver.back()
        time.sleep(1)
        continue

        # 중간,중간에 파일로 저장하기
    if i == 30 or i==50 or i==80:
        # 판다스로 만들기
        import pandas as pd
        df = pd.DataFrame.from_dict(dict, 'index')

        # 저장하기
        df.to_csv("melon_2021_12_chart.csv", encoding='utf-8-sig')
        time.sleep(3)

print('수집한 글 갯수: ', len(dict))
dict

...

크롤링 성공하면 글 제목 출력 할 수 있도록 입력해둔 print(i, title)과 print('수집한 글 갯수: ', len(dict)) 을 출력
dict 출력

#데이터프레임 만들기
df = pd.DataFrame.from_dict(dict, 'index')
df.head()

df['Genre']=df['New_Genre']
df

 

2021년 12월 차트의 장르에서 세부적으로 나누어져있어서 큰 틀로 맞추기 위해 New_Genre를 만들어 수정

#'발라드, 국내드라마','발라드,인디음악' 값을 '발라드'로 변경
df.loc[(df.New_Genre=='발라드, 인디음악'),'New_Genre']='발라드'
#'발라드, 국내드라마','록/메탈, 국내드라마' 값을 'OST'로 변경
df.loc[(df.New_Genre=='발라드, 국내드라마'),'New_Genre']='OST'
df.loc[(df.New_Genre=='록/메탈, 국내드라마'),'New_Genre']='OST'

(지금 보니 '발라드, 국내드라마' 변경하는 걸 발라드, OST 둘 다 했네,,,🫠 수정해야지..)

#R&B/Soul, 인디음악' 값을 'R&B/Soul'으로 변경
df.loc[(df.New_Genre=='R&B/Soul, 인디음악'),'New_Genre']='R&B/Soul'
#저장하기
df.to_csv("melon_2021_12_Chart_final.csv")

저장된 csv 파일

 

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#csv 불러오기
genre_2021_12 = pd.read_csv("melon_2021_12_Chart_final.csv")
genre_2021_12['New_Genre'].value_counts()

# 튜플 형태로 라벨 지정
labels = '랩/힙합', '발라드','댄스','POP','OST','R&B/Soul','성인가요','록/메탈','일렉트로니카','인디음악, 포크/블루스'
labels

genre_2021_12.columns

#'Unnamed:0' 칼럼 제거
genre_2021_12.drop(['Unnamed: 0'], axis = 1, inplace = True)
genre_2021_12

 

선호 장르를 파이차트로 표현

import matplotlib.pyplot as plt
import matplotlib as mpl

plt.rc('font', family='AppleGothic') # Mac
# 색(colors) 정하기, 차트 입체적으로(explode) 보이게
colors=['lightsteelblue','mistyrose','powderblue','bisque','thistle',\
        'lavender','lightgray','lightcyan','linen','pink']
explode=(0.05,0.05,0.05,0.05,0.07,0.08,0.1,0.1,0.1,0.1)
plt.figure(figsize=(15,15))

# pie chart 만들기(차트 띄우기, labels 달기, 각 조정, 시계방향순서, 그림자, 값 소숫점 표시)
plt.pie(genre_2021_12['New_Genre'].value_counts(), explode=explode, labels=None, startangle=90,\
        counterclock=False, shadow=True, autopct='%.1f',colors=colors)

# 라벨, 타이틀 달기
plt.title('<2021년 12월 월간 TOP100 장르별 비율>', fontsize=25, color='gray')

# 레전드 달기
plt.legend(labels,loc='lower left')

plt.show()

 

2021년 12월은 쇼미더머니 프로그램으로 선호하는 장르가 힙합이 많은 부분을 차지했고 그 다음으로는 발라드, 댄스 등이 있었다.

처음하는 프로젝트였고 배울 때는 쉽다고 느꼈지만 막상 직접 해보니 Selenium에서 element를 정확하게 찾는 것도 쉽지 않았고 지금 보니 실수도 하고 부족한 부분이 많이 보인다. 다음에는 더 수준을 높여야겠다! 

댓글