Melon Chart Top 100 crawling

Sooyoung Lim·2020년 5월 22일
1

코알라UNIV에서 5주차까지 배웠던 내용들을 모두 활용하여 수행할 수 있는 자체 제작 과제입니다.

멜론 TOP100 이동하기

메뉴를 선택하여 해당 탭의 Top 100 차트의 목록을 크롤링하고, 크롤링한 데이터를 xlsx 파일에 저장하기

Step 1. "실시간" 탭의 Top 100 데이터 추출

추출할 데이터 세트

데이터 변수명형식비고
rankint순위
imgSrcstring이미지 링크
songstring노래 제목
artiststring아티스트명, 복수 가능
albumstring앨범 제목
  • artist의 경우, 다음과 같이 두 명 이상의 artist인 경우가 존재합니다.

    해당 경우를 고려하여 데이터를 추출하시고, artistString이라는 변수에 '/' 로 artist를 구분하여 새로운 데이터 변수를 생성해주세요.

Step 2. 메뉴를 선택하여 해당 탭의 Top 100 데이터 추출

  • 메뉴 입력 양식입니다.
탭 이름메뉴 입력
실시간realtime
급상승rise
일간day
주간week
월간month
  • 코드 샘플은 다음과 같습니다.
menu = input("멜론차트 옵션을 입력하세요: ")

if menu == "realtime" :
    raw = requests.get("https://www.melon.com/chart/index.htm", headers={"User-Agent": "Mozilla/5.0"})
else :
    # 나머지 경우, url 주소의 규칙을 파악한 후 적절히 raw 변수를 설정해주시면 됩니다.
    # .htm 다음 따라오는 params의 값은 모두 무시하셔도 상관 없습니다. .htm까지를 url로 넣어주세요!
  • 앨범 커버 이미지의 경우, 입력했던 menu명과 동일한 폴더 를 생성하시고, urllib을 이용하여 '순위_노래제목.png'로 저장해주시면 됩니다. 예를 들어 순위가 1, 노래 제목이 '에잇(Prod.&Feat. SUGA of BTS)' 경우, 특수문자를 고려하여 적절히 replace함수와 slicing 기법을 이용하여 '1_에잇.png'로 저장해주시면 됩니다.

Step 3. 메뉴 별로 xlsx의 sheet를 생성하여 추출한 데이터 저장하기

sheet.append([int(rank), imgSrc, song, artistString, album])

로 저장하시면 됩니다!

  • sheet의 제목은 메뉴명과 동일하게 설정해주세요.
  • load_workbook()을 통해 엑셀파일 불러오기를 하는 경우 불러올 파일이 없다면 에러를 발생시킵니다. 이 때, try/except문을 활용하여
    불러올 파일이 없다면 새로운 파일을 생성하고,
    불러올 파일이 있다면 load_workbook()을 통해 해당 파일을 불러옵니다.
try:
    wb = openpyxl.load_workbook("MelonChartSheet.xlsx")
    # 코드 작성
    sheet.append(["순위", "앨범 사진 링크 주소", "곡 명", "아티스트 명", "앨범 명"])
    print("불러오기 완료")

except:
    wb = openpyxl.Workbook()
    # 코드 작성
    sheet.append(["순위", "앨범 사진 링크 주소", "곡 명", "아티스트 명", "앨범 명"])
    print("새로 파일을 만들었습니다")
  • 예를 들어, realtime에 대한 데이터를 한번 더 크롤링 시도하려 할 때, 이미 생성되어 있는 realtime xlsx sheet를 삭제하시고, 새로운 sheet를 생성해주세요. 구글링을 통해 sheet를 삭제하는 방법을 찾아주세요

추가 : 'datetime' 모듈을 활용하여 sheet 맨 위에 크롤링한 현재 시각을 추가해주세요.

역시 구글링하면 간단하게 현재 시각 추출하는 법을 알 수 있습니다!

결과


결과는 다음과 같습니다. 해당 폴더를 압축하시고 압축하신 폴더를 5월 28일 오후 2시까지 홈페이지에 제출해주세요!

month 메뉴에 대한 top 100 음악 앨범 커버 이미지입니다.


모든 과정을 다 수행하고 났을 때의 xlsx 결과물 모습입니다.

참고 답안

import requests
from bs4 import BeautifulSoup
import openpyxl
import datetime
from urllib.request import urlretrieve
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

########################################################################################################################

menu = input("멜론차트 옵션을 입력하세요: ")

now = datetime.datetime.now()

try:
    wb = openpyxl.load_workbook("MelonChartSheet.xlsx")
    sheetList = wb.sheetnames
    for sheet in sheetList :
        if menu == sheet :
            wb.remove(wb[menu])
            break
    sheet = wb.create_sheet(menu)
    sheet.append(["현재시각", now])
    sheet.append(["순위", "앨범 사진 링크 주소", "곡 명", "아티스트 명", "앨범 명"])
    print("불러오기 완료")

except:
    wb = openpyxl.Workbook()
    sheet = wb.active
    sheet.title = menu
    sheet.append(["현재시각", now])
    sheet.append(["순위", "앨범 사진 링크 주소", "곡 명", "아티스트 명", "앨범 명"])
    print("새로 파일을 만들었습니다")

########################################################################################################################

if menu == "realtime" :
    raw = requests.get("https://www.melon.com/chart/index.htm", headers={"User-Agent": "Mozilla/5.0"})
else :
    raw = requests.get("https://www.melon.com/chart/"+menu+"/index.htm", headers={"User-Agent": "Mozilla/5.0"})
html = BeautifulSoup(raw.text, 'html.parser')

########################################################################################################################

# 순위 : td > div.wrap.t_center > span.rank
# 앨범 사진 : div.wrap > a > img
# 곡명 : div.ellipsis.rank01 a
# 아티스트명 : div.ellipsis.rank02 > a:nth-of-type(num)
# 앨범명 : div.ellipsis.rank03 a

########################################################################################################################

for cnt in range(1, 3) :
    if cnt == 1 :
        container = html.select('tr#lst50')
    else :
        container = html.select('tr#lst100')

    for c in container:
        rank = c.select_one('td > div.wrap.t_center > span.rank').text.strip()
        print(rank)

        song = c.select_one('div.ellipsis.rank01 a').text.strip()
        print(song)

        artistNum = 1
        artistString = ""
        while True:
            if c.select_one('div.ellipsis.rank02 > a:nth-of-type(' + str(artistNum) + ')') is not None:
                artistString += (c.select_one('div.ellipsis.rank02 > a:nth-of-type(' + str(artistNum) + ')').text.strip() + '/')
            else:
                artistString = artistString[:-1]
                print(artistString)
                break
            artistNum += 1

        album = c.select_one('div.ellipsis.rank03 a').text.strip()
        print(album)

        img = c.select_one('div.wrap > a > img')
        imgSrc = img.attrs["src"]
        print(imgSrc)
        urlretrieve(imgSrc, menu+'/'+rank+'_'+song[:2]+'.png')

        sheet.append([int(rank), imgSrc, song, artistString, album])

        print("="*20)

wb.save("MelonChartSheet.xlsx")

0개의 댓글