성장 기록 블로그🌴
%1007 파이썬 웹크롤링 실습 - ( 멜론 차트에 있는 노래 제목과 가수 출력 하기 ! ) 본문
AI & BigData 교육과정/Python 관련
%1007 파이썬 웹크롤링 실습 - ( 멜론 차트에 있는 노래 제목과 가수 출력 하기 ! )
wlswls2s 2022. 10. 7. 17:46728x90
< 파이썬 웹크롤링 실습 내용 >
◆ 파이썬 기본
개념정리
멜론 음원데이터 수집하기 - ( 노래제목 , 가수 )
HTML 문서 관련 라이브러리 호출
# HTML 문서를 요청 / 응답을 받기 위한 라이브러리
import requests as req
# HTML 문서를 객체화 하기 위한 라이브러리 - BeautifulSoup
from bs4 import BeautifulSoup as bs
User-Agent 가져와서 사용자 검증 받아두기
# 서버에는 사용자임을 검증하는 특정한 값이 있다. => 그 값: User-Agent
# User-Agent : 브라우저 관련 정보를 보관하고 있는 변수
# 확인하는 방법 : 개발자도구 -> 네트워크 -> 특정파일선택 -> request headers영역
# 이 방법으로 request-headers에 있는 user-agent를 가져와야함
# 이 정보를 딕셔너리로 담음
# user-agent : 브라우저를 통해 요청하는 거야! 라고 서버에게 인지시키기 위한 값으로 활용
h = {"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"}
Melon 주소 사이트 가져오기
url = "https://www.melon.com/chart/"
url 변수에 저장 & req.get(url)
res = req.get(url, headers = h)
HTML문서 -> 객체화 -> bs(res.text , 'lxml')
html = bs(res.text , 'lxml')
멜론 차트의 가수 , 노래제목을 수집 한 후 출력해보기!
print("=== 멜론차트 1위 노래 제목===")
title = html.select_one("div.ellipsis.rank01 a").text
print(title)
=== 멜론차트 1위 노래 제목===
새삥 (Prod. ZICO) (Feat. 호미들)
print("=== 멜론차트 1위 노래 가수===")
# 그냥 div.ellipsis.rank02를 하면은 span 태그 아래 숨겨진 태그까지 출력이 됨
# 그 숨겨진 태그는 똑같은 가수 내용이 들어 가 있음
# 따라서, 노래 제목과 개수를 맞추기 위해
# span까지만 출력을 해서 개수를 노래제목과 맞춰줌
singer = html.select_one("div.ellipsis.rank02 > span").text
print(singer)
=== 멜론차트 1위 노래 가수===
지코 (ZICO)
멜론 차트의 모든 노래 제목을 가져오기
songs = html.select("div.ellipsis.rank01 a")
print("======멜론 Top 100 노래 제목 리스트=====")
for i in range(len(songs)) :
print(songs[i].text)
======멜론 Top 100 노래 제목 리스트=====
새삥 (Prod. ZICO) (Feat. 호미들)
After LIKE
Hype boy
Shut Down
Attention
Pink Venom
Rush Hour (Feat. j-hope of BTS)
LOVE DIVE
딱 10CM만
그때 그 순간 그대로 (그그그)
Cookie
Monologue
사랑은 늘 도망가
그라데이션
FOREVER 1
자격지심 (Feat. ZICO)
우린 그렇게 사랑해서
LAW (Prod. Czaer)
보고싶었어
우리들의 블루스
TOMBOY
사랑인가 봐
정이라고 하자 (Feat. 10CM)
SNEAKERS
내가 아니라도
나의 X에게
해요 (2022)
다시 만날 수... etc..
멜론 차트의 모든 노래 가수를 가져오기
singers = html.select("div.ellipsis.rank02 > span")
print("======멜론 Top 100 가수 리스트=====")
for i in range(len(singers)):
print(singers[i].text)
======멜론 Top 100 가수 리스트=====
지코 (ZICO)
IVE (아이브)
BLACKPINK
NewJeans
NewJeans
BLACKPINK
Crush
IVE (아이브)
10CM, BIG Naughty (서동현)
WSG워너비 (가야G)
NewJeans
임영웅
테이
소녀시대 (GIRLS' GENERATION)
10CM
강민경 (다비치), 잔나비 최정훈
윤미래, 비비 (BIBI)
BE'O (비오)
WSG워너비 (4FIRE)
임영웅
(여자)아이들
멜로망스
BIG Naughty (서동현)
주호
ITZY (있지)
임영웅
#안녕
경서
Charlie Puth
싸이 (PSY)
IVE (아이브)
김승민
LE SSERAFIM (르세라핌)
임영웅
임영웅
Charlie Puth
나연 (TWICE)
BE'O (비오)
aespa
김민석 (멜로망스)
임영웅
성시경
볼빨간사춘기
경서예지, 전건호
임영웅
임영웅
임영웅
BIGBANG (빅뱅)
임영웅
탑현
한동근
임영웅
Charlie Puth, 정국, 방탄소년단
The Kid LAROI, Justin Bieber
aespa
보라미유, MJ (써니사이드)
임영웅
임영웅
폴킴
임영웅
TWICE (트와이스)
방탄소년단
NMIXX
.
.
..
...
etc
=> 부모클래스 안에 태그들에 접근 할 때 find는 다소 귀찮게 접근해야하지만
Select는 '>' 기호를 이용해서 다소 간단하게 접근이 가능함
인덱스 요소 출력하기
singers[8].text
'10CM, BIG Naughty (서동현)'
노래 제목과 가수 한 번에 저장하기
# 노래 제목, 가수 한번에 출력하기
# 1. 노래 제목, 가수 정보를 저장할 리스트 생성
songlist = []
singerlist = []
for i in range(len(songs)) :
songlist.append(songs[i].text)
singerlist.append(singers[i].text)
# 2개의 리스트에 데이터를 저장했다면 잘 저장되었는지 크기로 확인하기!
len(songlist) , len(singerlist)
(100, 100)
리스트 내용을 데이터 프레임 생성을 위한 딕셔너리 생성하기!
# 데이터 프레임을 만들기 위한 딕셔너리 생성하기!
melon_dic = {"노래제목": songlist, "가수": singerlist}
# 데이터프레임을 만들 때 딕셔너리에 저장된 값들의 크기가 일치해야 함!
melon_df = pd.DataFrame(melon_dic)
< 호출 >
melon_df
< 결과 >
데이터 프레임에 담은 내용을 엑셀 파일 형태로 저장하기
# melon_df.to_excel => 엑셀파일 형태로 저장됨
melon_df.to_excel("멜론차트100.xlsx")
데이터 프레임에 담은 내용을 csv 파일 형태로 저장하기
# csv 파일로 저장하고 excel로 http://localhost:8803/notebooks/%ED%81%AC%EB%A1%A4%EB%A7%81/22.10.07%20Ex02.%20%EB%A9%9C%EB%A1%A0%20%EC%9D%8C%EC%9B%90%EB%8D%B0%EC%9D%B4%ED%84%B0%20%EC%88%98%EC%A7%91%ED%95%98%EA%B8%B0.ipynb#%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%94%84%EB%A0%88%EC%9E%84%EC%97%90-%EB%8B%B4%EC%9D%80-%EB%82%B4%EC%9A%A9%EC%9D%84-csv-%ED%8C%8C%EC%9D%BC-%ED%98%95%ED%83%9C%EB%A1%9C-%EC%A0%80%EC%9E%A5%ED%95%98%EA%B8%B0열면 한글이 깨질 수 있음.
#하지만 막상 불러오면 별 문제 없음 -> 메모장으로도 확인 가능
# csv파일을 안 깨지게 열고싶으면 encoding으로 EUC-KR 지정해주면 됨.
melon_df.to_csv("멜론차트100_2.csv" , encoding = "EUC-KR")
728x90