on
파이썬을 활용한 실시간 멜론 TOP 100 차트 분석하기!
파이썬을 활용한 실시간 멜론 TOP 100 차트 분석하기!
학교에서 진행한, 2021 PNU SW-X 문제해결 경진대회에서 수상했어요 >
그 과정을, 복기해보는 시간을 가져보도록 할게요. 또 추가적인 기능도 구현해 볼게요.
코랩으로 만든 파이썬 프로젝트를, 장고로 만든 웹 사이트와 연결하는 것을 이번 개인 프로젝트의 목표로 두고 있어요.
파이썬을 활용해서, 멜론 차트 순위를 확인해 볼까요?
TOP 100이 아닌, 사용자가 원하는 만큼의 순위를 확인해 볼게요! ㅎㅎ
ex) 사용자 : 10위까지만 확인하고싶어!
우선, requests 모듈과, BeautifulSoup 모듈을 사용할거에요.
import requests from bs4 import BeautifulSoup
requests모듈은, 파이썬에서 HTTP 요청을 보내는 모듈이에요.
BeautifulSoup모듈은, 파싱을 위한 파이썬 라이브러리입니다.
if __name__ == "__main__": RANK = int(input("몇 위까지의 노래를 보고 싶으신가요? ")) print("-"*50) header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43'} req = requests.get('https://www.melon.com/chart/index.htm', headers=header) html = req.text parse = BeautifulSoup(html, 'html.parser')
여기서 마주치는 if __name__ == "__main__" : 은 무엇일까요? (구글링하다 찾은 코드...)
인터프리터에서 직접 실행했을 경우에만, if 문 내의 코드를 돌리라는 명령인데요, 뭔가 C의 main()과 관련이 있나? 싶어서 따로 찾아봤어요.
파이썬에서 __name__이라는 내장변수는 현재 모듈의 이름을 담고 있는 내장변수이다. 이는 직접 실행된 모듈의 경우,
__main__이라는 값을 가지며, 직접 실행되지 않은 import 된 모듈은 모듈의 이름(파일명)을 가지게 된다.
따라서 "실행"했을 때(인터프리터가 직접 실행) 돌아가는 프로그램임을 알 수 있네요.
RANK 값에 사용자 입력 값을 줘요. 20위까지 보고싶으면 20을 입력.
headers
멜론의 경우, User-Agent를 바꿔줘야 크롤링이 가능하다 하네요. 구글에서 검색해서 가져다 씁시다!
<여기서 User-Agent란...>
HTTP 요청을 보내는 디바이스와 브라우저 등 사용자 소프트웨어의 식별 정보를 담고 있는 request header의 한 종류이다. 임의로 수정될 수 없는 값이고, 보통 HTTP 요청 에러가 발생했을 때 요청을 보낸 사용자 환경을 알아보기 위해 사용한다.
Mozilla 정보/버전 + 운영체제 정보 + 렌더링 엔진 정보 + 브라우저 형태로 노출.
복잡한 줄 알았더니 그냥 위 형식에 맞게 갖다 쓰면 되네요.
requests.get()함수.
requests 모듈에 있는 requests.get 함수를 사용해서 멜론 주소로 GET 요청을 보내요. 그리고 응답을 req에 저장합니다.
html 은 req(html 코드)를 텍스트로 변환한 것이고요.
html.parser
BeautifulSoup 모듈을 이용하여, 해당 문서를 파싱해줍니다.
titles = parse.find_all("div", {"class": "ellipsis rank01"}) singers = parse.find_all("div", {"class": "ellipsis rank02"}) title = [] singer = []
find_all() 함수 : 해당 조건에 맞는 모든 태그들을 가져온다.
멜론 사이트에서 F12를 눌러 개발자 도구로 들어가 줍니다.
여기가 진짜 처음할 때는 몰라서 힘들었는데요, 쉬운 방법이 있었어요....흑
커서를 갖다대면 원하는 정보가 들어있는 코드를 확인할 수 있어요! 이제 이걸 find_all()함수를 사용해서 가져와줍니다. div를 모두 찾고, 그 중 원하는 class값을 입력해 주어 찾아줍니다.
빨간색 저걸 눌러주면 커서를 이용해서 원하는 코드의 위치를 찾을 수 있어요. 저걸 모르고 일일히 찾다가 눈 빠질뻔ㅠ
가져온 값들을, 각각 titles와 singers에 넣어줘요.
그다음 title, singer 두 빈 리스트를 만들어 줍니다.
for t in titles: title.append(t.find('a').text) for s in singers: singer.append(s.find('span', {"class": "checkEllipsis"}).text) for i in range(RANK): print("랭킹 : %d위" % (i + 1)) print('곡명 : %s' % title[i]) print('가수 : %s' % singer[i]) print("-"*50)
같은 방식으로, 이번에는 find_all()함수가 아닌, find()함수를 사용하여 원하는 "제목"과 "가수"명으로 범위를 좁혀주어 뽑아냅시다.
find()와 find_all()의 차이는 직관적으로 느껴지다싶이..
find_all(): 해당 조건에 맞는 모든 태그들을 가져온다.
find(): 해당 조건에 맞는 하나의 태그를 가져온다. 중복이면 가장 첫 번째 태그를 가져온다.
그리고 앞서 입력해준 RANK만큼, for 문을 돌려주며 받아온 값들을 차례차례 출력해 줍시다.
완성한 코드!
import requests from bs4 import BeautifulSoup if __name__ == "__main__": RANK = int(input("몇 위까지의 노래를 보고 싶으신가요? ")) print("-"*50) header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43'} req = requests.get('https://www.melon.com/chart/index.htm', headers=header) html = req.text parse = BeautifulSoup(html, 'html.parser') titles = parse.find_all("div", {"class": "ellipsis rank01"}) singers = parse.find_all("div", {"class": "ellipsis rank02"}) title = [] singer = [] for t in titles: title.append(t.find('a').text) for s in singers: singer.append(s.find('span', {"class": "checkEllipsis"}).text) for i in range(RANK): print("랭킹 : %d위" % (i + 1)) print('곡명 : %s' % title[i]) print('가수 : %s' % singer[i]) print("-"*50)
코랩에서 출력결과는 다음과 같다. 이제 비주얼 스튜디오로 옮겨서 작업해야겠다.
from http://brilliantcse.tistory.com/6 by ccl(A) rewrite - 2021-12-28 06:01:49