AI, 시각화, 빅데이터 기초

melon 장르별 탑 50곡 정적 크롤링하기

til_t 2021. 5. 27. 17:18

 

1. 멜론 장르 음악에서 각 장르별 url 분석

https://www.melon.com/genre/song_list.htm?gnrCode= 를 유지하며 발라드, 댄스, 랩/힙합 등과 같이 왼쪽부터 시작해서 n번째인 장르는 곧 장르코드가 GN0n00임을 알 수 있다.

ex) 포크/블루스는 8번째이므로 포크/블루스를 클릭했을 때 주소는 https://www.melon.com/genre/song_list.htm?gnrCode=GN0800

 

그래서 입력한 장르별로 코드를 저장하도록 다음과 같이 코드를 짰다.

while(True):
    genre = input("음악 장르 입력(발라드, 댄스, 힙합, 알앤비, 인디, 록, 트로트, 포크) : ")
    count = 0

    if genre == "발라드":
        gnrCode = "GN0100"
        break
    elif genre == "댄스":
        gnrCode = "GN0200"
        break
    elif genre == "힙합":
        gnrCode = "GN0300"
        break
    elif genre == "알앤비":
        gnrCode = "GN0400"
        break
    elif genre == "인디":
        gnrCode = "GN0500"
        break
    elif genre == "록":
        gnrCode = "GN0600"
        break
    elif genre == "트로트":
        gnrCode = "GN0700"
        break
    elif genre == "포크":
        gnrCode = "GN0800"
        break
    else:
        print("장르 입력이 잘못 되었습니다. 다시 입력해주십시오.")

 

2. url을 통해 raw를 가져오고 html로 바꾼다.

 

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'}
melon_url = "https://www.melon.com/genre/song_list.htm?gnrCode=" + gnrCode
raw = requests.get(melon_url, headers = header)
soup = BeautifulSoup(raw.text, "html.parser")

멜론은 header가 필요했다.

그래서 requests.get의 두 번째 인자에 headers에 지정한 헤더를 넣어줬다.

 

3. html 태그를 통해 원하는 정보를 find 계열 함수로 찾아 출력한다.

 

 

-> <tbody>에 장르별 인기 노래가 나열되어 있다.

 

 

-> 그중 class가 ellipsis rank01인 태그에 각 노래 제목이 있다.

 

 

-> class가 ellipsis rank02인 태그에 각 가수 이름이 있다.

 

그 모든 나열된 값들을 zip으로 모아 노래와 제목을 같이 출력한다.

순위도 출력하고 싶으므로 count 변수를 만들어 루프를 돌 때마다 +1를 하도록 한다.

그리고 자세히 보면 클래스에 바로 원하는 값이 있는 게 아니라

 

클래스 안의 <a> 태그에 원하는 값이 있기 때문에 루프를 돌리면서 이 값도 find하고 text로 바꿔준다.

 

box = soup.find("tbody")

all_singer = box.find_all("div", {"class":"ellipsis rank02"})
all_title = box.find_all("div", {"class":"ellipsis rank01"})

print(genre + "의 TOP 50곡")

for singer, title in zip(all_singer, all_title):
    count += 1
    print(str(count) + "위. " + title.find("a").text + " - " + singer.find("a").text)

 

4. 실행 결과

 

현재 댄스 장르 인기곡 순위

그리고 크롤링한 결과

 

5. 전체 코드

 

import requests
from bs4 import BeautifulSoup

while(True):
    genre = input("음악 장르 입력(발라드, 댄스, 힙합, 알앤비, 인디, 록, 트로트, 포크) : ")
    count = 0

    if genre == "발라드":
        gnrCode = "GN0100"
        break
    elif genre == "댄스":
        gnrCode = "GN0200"
        break
    elif genre == "힙합":
        gnrCode = "GN0300"
        break
    elif genre == "알앤비":
        gnrCode = "GN0400"
        break
    elif genre == "인디":
        gnrCode = "GN0500"
        break
    elif genre == "록":
        gnrCode = "GN0600"
        break
    elif genre == "트로트":
        gnrCode = "GN0700"
        break
    elif genre == "포크":
        gnrCode = "GN0800"
        break
    else:
        print("장르 입력이 잘못 되었습니다. 다시 입력해주십시오.")

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'}
melon_url = "https://www.melon.com/genre/song_list.htm?gnrCode=" + gnrCode
raw = requests.get(melon_url, headers = header)
soup = BeautifulSoup(raw.text, "html.parser")

box = soup.find("tbody")

all_singer = box.find_all("div", {"class":"ellipsis rank02"})
all_title = box.find_all("div", {"class":"ellipsis rank01"})

print(genre + "의 TOP 50곡")

for singer, title in zip(all_singer, all_title):
    count += 1
    print(str(count) + "위. " + title.find("a").text + " - " + singer.find("a").text)