본문 바로가기
Python/Python_Crawling

크롤링 : 멜론

by Mr.DonyStark 2024. 2. 2.

□ 목적

  ○ 차트 1~100위 곡명, 아티스트, 엘범명 데이터 크롤링

  ○ 아티스트 세부정보 접속 링크 추출

  ○ 엘범명 세부정보 접속 링크 추출

 

□ 코딩과정

  ○ 라이브러리 호출

  ○ 함수정의 : 아티스트, 엘범 세부정보 접속시 자바스크립트 코드 안에 있는 번호 추출을 위해 함수지정

  ○ *  .text 는 해당 태그 또는 하위 태그안의 텍스트를 출력하지만, .string은 특정 태그값이 지정되었을 때 정확한텍스트를 추출함

 

 

□ 코드

# 라이브러리 호출
import requests
import re
from bs4 import BeautifulSoup

# 크롤링 페이지 입력
# 네이버뷰 주소 + 검색키워드
target_url = 'https://www.melon.com/chart/index.htm'
print(f'접속페이지\t:\t{target_url}')
#header : User-Agent 설정

# 함수정의
def filter_num(get_num_info):
    # 리스트 컴프리헨션 / 자바스크립트 속 번호코드를 추출하기위해 사용
    # isdigit()을 활용하여 들어온 값에서 숫자만 판별하여 저장
    # .join()함수를 사용하여 숫자 한개씩 분리되어있는 값을 병합
	song_num = "".join([num for num in get_num_info if num.isdigit()])
    return info_num
    
    # 위에 기재한 리스트컴프리헨션으로 대체
    # info_num = list()
    # for num in get_num_info:
    #     if num.isdigit():  # .isdigit() 받은문자가 숫자형식인지 판단해줌. 숫자이면리스트에 추가
    #         info_num.append(num)
    # info_num = ''.join(info_num) # join() 메서드를 사용하여 리스트의 각 요소를 이어붙여서 하나의 문자열 + 리스트요소를 한요소로 합침
    # return info_num


# 데이터 요청
req_get_url = requests.get(target_url, headers = ma_headers) #검색어관련 뷰 페이지에 데이터 request 및 get 요청  
get_html = req_get_url.text  #get한 데이터를 텍스트로 받음
parser_soup = BeautifulSoup(get_html, 'html.parser') #BeautifulSoup 을 활용해 html.parser로 데이터 구분
print(req_get_url.request.headers) #헤더정보 확인

rank_50 = parser_soup.select('.lst50') #1~100까지 클래스명
rank_100 = parser_soup.select('.lst100') #51~100부터 클래스명이 바뀜
rank_list = rank_50 +rank_100 #1~50,51~100 리스트 합침

#위코드를 대체가능한 코드
#find_all로 모두가져오기 : 클래스가 list50, list100 네임을 가진 요소들을 찾아라
#rank_list = parser_soup.find_all(class_ = ['list50','list100'])


for i in rank_list:
    rank_detail = i.select_one('span.rank').text #랭크 : span 태그의 클래스명이 rank 인 것
    rank_title = i.select_one('.ellipsis.rank01 a').text.strip().replace('\t','') #곡명 : div 태그의 클래스명이 ellipsis.rank01 인것에서 하위 태그가 a인것.  부모태그의 바로아래 자식태그라면 > 로 연결.
    rank_singer = i.select_one('.ellipsis.rank02 > a').string #가수 : div 태그의 클래스명이 ellipsis.rank02 인것에서 하위 태그가 a인것. 부모태그의 바로아래 자식태그라면 > 로 연결.
    rank_album = i.select_one('.ellipsis.rank03 > a').string #엘범 : div 태그의 클래스명이 ellipsis.rank03 인것에서 하위 태그가 a인것. 부모태그의 바로아래 자식태그라면 > 로 연결.

    #가수 링크번호 추출을 위해 클래스네임이 .ellipsis.rank02 이며 하위태그가 a인것이며 그속에 href 속성값 추출
    s_link = i.select_one('.ellipsis.rank02 > a')
    singer_link = filter_num(s_link['href'])  #위에서 정의한 함수호출 및 s_link 중 href 속성값을 매개변수로 받아 링크번호만 추출 
    #엘범 링크번호 추출을 위해 클래스네임이 .ellipsis.rank03 이며 하위태그가 a인것이며 그속에 href 속성값 추출
    a_link = i.select_one('.ellipsis.rank03 > a')
    album_link = filter_num(a_link['href'])  #위에서 정의한 함수호출 및 a_link 중 href 속성값을 매개변수로 받아 링크번호만 추출

    print('')
    print('https://www.melon.com/artist/timeline.htm?artistId='+str(singer_link))
    print('https://www.melon.com/album/detail.htm?albumId='+str(album_link))
    print('album_link_url')    
    print(f'{rank_detail} 등\t:\t{rank_title}\n앨범명\t:\t{rank_album} \n가수\t:\t{rank_singer}')