멜론 차트 크롤링(Melon Chart Crawling)

Todo

  1. requests or urllib로 html 불러오기
  2. soup = BeautifulSoup(html)

1. requests or urllib로 html 불러오기

Reference

request 모듈 문서

  • requests: HTTP 요청을 보내는 모듈
import requests # HTTP 요청을 보내는 모듈
 
url = "https://www.melon.com/chart/index.htm"
# 현재 사용자가 어떤 클라이언트(운영체제와 브라우저 같은 것)를 이용해 요청을 보냈는지 확인
req_header = {'user-agent': 'Chrome/125.0.6422.142'}
 
res = requests.get(url, headers= req_header)
html = res.text

2. soup = BeautifulSoup(html)

Reference

BeautifulSoup 문서

  • BeautifulSoup: HTML과 XML 파일로부터 데이터를 뽑아내기 위한 파이썬 라이브러리
from bs4 import BeautifulSoup
 
soup = BeautifulSoup(html)

Memo

  • 하나씩 정보를 끌어다와서 확인 후 한곡의 모든 항목이 끝나면 딕셔너리로 모은 뒤 for loop를 사용하여 100개 출력하기

.find, .find_all 함수

순위 나타내기

  • 순위를 나타내는 상위 태그의 클래스가 lst50,lst100으로 나뉘어져 있어 150위, 51100위로 나눠서 출력해야한다.

  • 먼저 둘로 나눈다.

song_rank50 = soup.findAll('tr', class_='lst50')
song_rank100 = soup.findAll('tr', class_='lst100')
  • 먼저 순위는 연습으로 1위만 출력하게 해보았다. song_rank50[0]은 1위를 나타낸다.
rank_1 = song_rank50[0]
  • 순위가 들어가 있는 태그를 찾아 넣는다.
rank_1.find('div', class_='wrap t_center').text
 
# 출력값: '1위'

곡 이름 나타내기

  • 마찬가지로 연습용으로 1위 곡명을 출력해보았다.
rank_1.find('div', class_ = 'ellipsis rank01').text
 
# 출력값: '\nSupernova\n'

가수 이름 나타내기

  • 1위 가수명을 출력해보았다.
rank_1.find('div', class_ = 'ellipsis rank02').text
 
# 출력값: '\naespaaespa\n'

1~100위까지 순위, 곡명, 가수명 출력하기

  • 처음에 데이터를 받을 딕셔너리가 필요하다.
  • 딕셔너리는 나중에 DataFrame으로 만들기 위해 키값을 설정해두는 것이 좋다.
melon_dict = {} # 이것은 내가 원하는 키값으로 지정할 수 없다.
 
# 내가 원하는 값으로 키값을 지정할 수 있다.
melon_dict = {"rank":[],"song_name":[],"singer_name":[]} 
  • for문을 0100 까지 100번 돌려 1위100위까지 데이터가 받아지게 한다.
  • 이후 연습했던 순위, 곡명, 가수명을 for문안에 넣는다.
  • 연습용 출력값에서 보였던 \n을 없애기 위해 마지막에 .strip('\n') 을 넣는다.
for i in range(0, 100):
    if i < 50:
        rank = song_rank50[i].find('div', class_='wrap t_center').text
        song_name = song_rank50[i].find('div',class_='ellipsis rank01').text.strip('\n')
        singer_name = song_rank50[i].find('span',class_='checkEllipsis').text.strip('\n')
        
    elif i >= 50 or i < 100:
        rank = song_rank100[i-50].find('div', class_='wrap t_center').text
        song_name = song_rank100[i-50].find('div',class_='ellipsis rank01').text.strip('\n')
        singer_name = song_rank100[i-50].find('span',class_='checkEllipsis').text.strip('\n')
  • 이후 만들어둔 melon_dict를 for문안에서 돌려 for문을 돌려서 나오는 데이터들을 넣어준다.
	melon_dict["rank"].append(rank)
    melon_dict["song_name"].append(song_name)
    melon_dict["singer_name"].append(singer_name)
  • 출력값:

DataFrame 생성

  • melon_dictDataFrame으로 만들어준다.
import pandas as pd
 
pd.DataFrame(melon_dict)
  • 출력값:

최종 코드

import requests # HTTP 요청을 보내는 모듈
from bs4 import BeautifulSoup # BeautifulSoup를 쓸 수 있게 하는 모듈
import pandas as pd # pandas 사용 모듈
 
url = "https://www.melon.com/chart/index.htm"
req_header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
 
res = requests.get(url, headers= req_header)
html = res.text
 
soup = BeautifulSoup(html)
 
# 데이터를 받아줄 빈 딕셔너리를 만든다. 만들때 키값 설정하는 것이 중요!!
melon_dict = {"rank":[],"song_name":[],"singer_name":[]}
 
# for문을 0부터 99까지 100번 실행 (1위 ~ 100위)
for i in range(0, 100):
    if i < 50: # 1~50위까지의 데이터
        rank = song_rank50[i].find('div', class_='wrap t_center').text
        song_name = song_rank50[i].find('div',class_='ellipsis rank01').text.strip('\n')
        singer_name = song_rank50[i].find('span',class_='checkEllipsis').text.strip('\n')
 
    elif i >= 50 or i < 100: # 51~100위까지의 데이터
        rank = song_rank100[i-50].find('div', class_='wrap t_center').text
        song_name = song_rank100[i-50].find('div',class_='ellipsis rank01').text.strip('\n')
        singer_name = song_rank100[i-50].find('span',class_='checkEllipsis').text.strip('\n')
 
	# for문을 돌려가며 melon_dict에 데이터 입력
    melon_dict["rank"].append(rank)
    melon_dict["song_name"].append(song_name)
    melon_dict["singer_name"].append(singer_name)
 
pd.DataFrame(melon_dict)