구글 코랩(Colab)에서 멜론 시대별 차트 정보 크롤링 방법

 오늘은 국내 대중가요 가사 텍스트 데이터를 이용하여 감정 분석을 진행할 목적으로

노래 정보를 파이썬으로 추출하였습니다.

구글 Colaboratory에서 동작하는 관련 소스코드를 공유합니다.

1. 추출하려는 노래 목록

  • 멜론 > 멜론차트 > 시대 > 2023년도 1위 ~ 100위
  • 해당 URL : https://www.melon.com/chart/age/index.htm?chartType=YE&chartGenre=KPOP&chartDate=2023&moved=Y&idx=1

2. 파이썬 소스코드

import re
import requests
from bs4 import BeautifulSoup
import pandas as pd
from time import sleep
import os
from tqdm import tqdm

# 2023년대 노래 시대별차트
headers = {
    'User-Agent': ('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                   '(KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36')
}

age_url = "https://www.melon.com/chart/age/list.htm"

params = {
    'idx': '1',
    'chartType': 'YE',     # 10년 단위로 검색하는 부분과 연관
    'chartGenre': 'KPOP',  # 가요검색: KPOP, 팝송검색: POP
    'chartDate': '2023',   # 검색연도
    'moved': 'Y',
}

response = requests.get(age_url, params=params, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
song_list = soup.select('.lst50, .lst100')

# 데이터프레임 초기화
columns = ['chartDate', 'rank', 'title', 'singer', 'album_name', 'release_date', 'genre', 'lyric', 'composer', 'lyricist', 'arranger']
song_data = pd.DataFrame(columns=columns)

# tqdm 라이브러리로 진행 상황 바 표시
for i, meta in tqdm(enumerate(song_list, 1), total=len(song_list), desc="Processing songs"):
    rank = i
    try:
        title = meta.select('a[href*=playSong]')[0].text
    except:
        title = meta.select('.wrap_song_info .ellipsis')[0].text
    title = title.strip()

    song_id_html = str(meta.select('a[onclick*=SongDetail]'))
    matched = re.search(r"\'(\d+)\'", song_id_html)
    song_id = matched.group(1)
    song_url = 'https://www.melon.com/song/detail.htm?songId=' + song_id

    response = requests.get(song_url, params=params, headers=headers)
    soup = BeautifulSoup(response.text, 'html.parser')

    # 가수
    singer_html = soup.select('.wrap_info .artist a')
    singer_s = ', '.join([html['title'] for html in singer_html if html['title']]) if singer_html else 'Various Artists'

    # 앨범명
    album_name = soup.select('.list dd')[0].get_text(strip=True)

    # 발매날짜
    release_date = soup.select('.list dd')[1].get_text(strip=True)

    # 장르
    genre = soup.select('.list dd')[2].get_text(strip=True)

    # 가사
    lyric = '없음'
    lyric_html = soup.select_one('.section_lyric .wrap_lyric .lyric')
    if lyric_html:
        lyric = lyric_html.get_text(strip=True, separator='\n')

    # 작사, 작곡, 편곡
    member_roles = {'작사': 'lyricist', '작곡': 'composer', '편곡': 'arranger'}
    members = {v: '' for k, v in member_roles.items()}
    for entry in soup.select('.section_prdcr .list_person .entry'):
        role = entry.select_one('.meta').get_text(strip=True)
        if role in member_roles:
            members[member_roles[role]] = entry.select_one('.artist').get_text(strip=True)

    # 데이터프레임에 추가
    row = pd.Series([params['chartDate'], rank, title, singer_s, album_name, release_date, genre, lyric, members['composer'], members['lyricist'], members['arranger']], index=song_data.columns)
    song_data = pd.concat([song_data, pd.DataFrame([row])], ignore_index=True)

    sleep(1)  # IP 차단 방지용

참고 소스코드 : https://blog.naver.com/21ahn/221820216442

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments