rainbow/추천시스템

[크롤링] 멜론 플레이리스트 수록곡, 가사 크롤러 만들기

윌_ 2023. 9. 17. 12:47

추천시스템 구현을 고민하다 멜론 플레이리스트 크롤러를 만들어보게 되었습니다.

만들어진 크롤러가 아닌, 제가 원하는대로 크롤러를 만들어본 건 처음인 듯한데요!

이를 기록하기 위해 포스팅합니다 :) 

 

해볼 건! 멜론 사이트에서 원하는 플레이리스트에 수록된 곡과 해당 곡 가사, 가수명을 긁어와보려합니다.

 

멜론에 들어가 원하는 플레이리스트 페이지에 들어가 링크만 아래 코드에서 수정해주면 크롤러 구현이 가능합니다.

pip install selenium

from selenium import webdriver
import time
from time import sleep
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import pandas as pd

driver = webdriver.Chrome()
driver.implicitly_wait(2)

#멜론 플레이리스트 링크로 접속
driver.get('https://www.melon.com/mymusic/dj/mymusicdjplaylistview_inform.htm?plylstSeq=524401771')
driver.implicitly_wait(2)

# 데이터프레임 생성
lyrics_df = pd.DataFrame(columns=['Song', 'Singer', 'Lyrics'])


song = []
singer = []
lyrics = []

#--------------------------------------------------------------------------------------------------

# 플레이리스트 내 수록곡 Length
song_list = driver.find_elements(By.XPATH,'//*[@id="frm"]/div/table/tbody')

song_list_li = []

for element in song_list:
    tr_elements = element.find_elements(By.TAG_NAME, 'tr')
    song_list_li.extend(tr_elements)
    driver.implicitly_wait(2)
song_list_len = len(song_list_li)

#--------------------------------------------------------------------------------------------------

# 수록곡 수많큼 반복  
for i4 in range(1, song_list_len+1):# 현재는 한페이지에 속한 곡만 긁어옴(최대 50곡)


    ## 50곡 이상 긁어오기 위해선 if문을 활용해 페이지 이동을 한 번 해주어야함
    # 아래 같은 형태로!(*이 코드에 적용되지는 않음)
    # if i4 > 50 :
    #     driver.find_elements(By.XPATH,'//*[@id="frm"]/div[2]/span/a').click()
    #     driver.implicitly_wait(2)
    #     sleep(0.3)

    
    # 가사 페이지 클릭
    lyric_button_list = driver.find_elements(By.XPATH,'//*[@id="frm"]/div/table/tbody/tr[{}]/td[4]/div/a'.format(i4)) 
                                                          
    if lyric_button_list:
        lyric_button = lyric_button_list[0] 
        lyric_button.click()
    else:
        print(f"No element found for index {i4}")
    driver.implicitly_wait(1)
    sleep(0.5)

    # 가사 페이지에서 구동
    try: 
        
        # 가사 크롤링
        lyrics_elements = driver.find_elements(By.XPATH,'//*[@id="d_video_summary"]')
        
        lyrics_text = ' '.join([element.text for element in lyrics_elements])
        lyrics.append(lyrics_text)
        

        # 곡명 크롤링
        song_name_elements = driver.find_elements(By.XPATH,'//*[@id="downloadfrm"]/div/div/div[2]/div[1]/div[1]')
        
        song_name = ' '.join([element.text for element in song_name_elements])
        song.append(song_name)


        # 가수명 크롤링
        artist_name_elements = driver.find_elements(By.XPATH,'//div[@class="artist"]/a/span')
        
        artist_names = ' '.join([element.text for element in artist_name_elements])
        singer.append(artist_names)
        
    except: pass

    driver.back()
    sleep(0.5)

# 데이터 프레임 
lyrics_df = pd.DataFrame.from_dict({'Song': song, 'Singer' : singer, 'Lyrics': lyrics}, orient ='index').T

# 파일 저장
filename = '비가 오고 음악이 흐르면 추억이 생각날 때 듣는 힙합/알앤비 Part.3.csv'
lyrics_df.to_csv(filename, index=False, encoding='utf-8')