Web Data

yoong·2023년 5월 18일

6.EDA

목록 보기
6/8

[끄적끄적]
실습 영상은 네이버 영화 평점이였으나, 해당 서비스가 종료되어 실습하지 못함.
그래서 다음영화랑 왓챠로 도전했으나 둘다 url에 날짜가 안떠서 실패...
이번 실습해보려고,,,, '네이버 영화평점 -> 왓챠 -> 다음영화 -> 멜론뮤직 ->벅스뮤직' 옮겨다님 허허

Bugs Music

  • 현재 기준, top 100의 '랭킹,곡이름,가수명,날짜'값을 크롤링함

1. 리스트를 위한 코드

1-1. requirments

import pandas as pd
from urllib.request import Request,urlopen
from fake_useragent import UserAgent
from bs4 import BeautifulSoup

1-2.

url = "https://music.bugs.co.kr/chart/track/realtime/total?chartdate=20230517"
ua = UserAgent()
ua.ie

req = Request(url, headers={"user-agent" : ua.ie})
response = urlopen(req)
soup = BeautifulSoup(response,"html.parser")
print(soup.prettify())

1-3. 첫번째 제목,가수,순위값 가져오기

#노래 제목
soup.find_all("p","title")[0].a.string

#노래 가수
soup.find_all("p","artist")[0].a.string

#순위
soup.find_all("div","ranking")[0].strong.string

1-4. 제목,가수,순위값 리스트 만들기

#노래 리스트
end = len(soup.find_all("p","title"))
song_list = [soup.find_all("p","title")[n].a.string for n in range(0,end)]
song_list

#가수 리스트
end = len(soup.find_all("p","artist"))
song_artist = [soup.find_all("p","artist")[n].a.string for n in range(0,end)]
song_artist

#순위 리스트
end = len(soup.find_all("div","ranking"))
song_rank = [soup.find_all("div","ranking")[n].strong.string for n in range(0,end)]
song_rank

1-5. 개수 확인작업을 통해 맞게 들어간지 확인하기

len(song_list),len(song_rank),len(song_artist)

2. 자동화를 위한 코드

2-1.date

date = pd.date_range("2023.02.08", periods=100, freq="D")
date
#date모양 'yyyy.mm.dd'형태로 바꾸어주기
date[0].strftime("%Y.%m.%d")

2-2 문자열 format
(예시) 문자열 format

#문자열 format
test_string = "Hi, I'm {name}"
test_string.format(name="kim")

2-3 자동화

import time
from tqdm import tqdm

song_date = []
song_rank = []
song_list = []
song_artist = []


for today in tqdm(date):
    url = "https://music.bugs.co.kr/chart/track/realtime/total?chartdate={date}"
    response = urlopen(url.format(date=today.strftime("%Y%m%d")))
    soup = BeautifulSoup(response, "html.parser")
    
    end = len(soup.find_all("p","title"))
    
    
    song_date.extend([today for _ in range(0,end)]) #today라는 변수에 넣어줌 
    song_list.extend([soup.select("p.title")[n].find("a").get_text() for n in range(0,end)])
    song_rank.extend([soup.find_all("div","ranking")[n].strong.string for n in range(0, end)])
    song_artist.extend([soup.find_all("p","artist")[n].a.string for n in range(0,end)])
    
    time.sleep(0.5) #너무속도가 빠르면 사이트에서 차단할수도있기때문에 넣어줌 

2-4 길이 및 리스트 잘 들어갔는지 확인

len(song_date),len(song_rank),len(song_list),len(song_artist)
song_artist[:5]

2-5 데이터프레임

song = pd.DataFrame({
    "date" : song_date,
    "rank" : song_rank,
    "title" : song_list,
    "artist": song_artist
})

song

2-6. 숫자 산출을 위해 데이터 타입 변경

#데이터타입 확인
song.info()
#숫자를 산술할 수있게 바꾸어줌 
song["rank"].astype(int)

2-7. 데이터 저장

# 데이터 저장

song.to_csv(
    "../data/03. bugs_music_data.csv",sep=",",encoding="utf-8"
)

3. 시각화를 위한 코드

1)

3-1 파일 불러오기

import numpy as np
import pandas as pd
song = pd.read_csv("../data/03. bugs_music_data.csv",index_col=0)
song.tail()

3-2 피봇테이블

song_unique = pd.pivot_table(data=song, index="title", aggfunc=np.sum)
song_unique
song_best = song_unique.sort_values(by="rank", ascending=True) 
song_best.head()

2)

3-3 Say My Name 순위변화표 만들기

tmp = song.query("title == ['Say My Name']")
tmp

3-4 Say My Name 순위변화표 시각화

import matplotlib.pyplot as plt
from matplotlib import rc

rc("font", family= "Arial Unicode Ms")
%matplotlib inline
plt.figure(figsize=(20,8)) # x= 20 y= 8
plt.plot(tmp["date"],tmp["rank"]) 
#선그래프 : x축은 날짜 ,y축은 평점 - 날짜에 따른 평점 변화를 선그래프로 표현(시계열)
plt.title("날짜별 랭킹")
plt.xlabel("날짜")
plt.ylabel("랭킹")
plt.xticks(rotation="vertical")
plt.legend(labels=["랭킹 추이"],loc ="best")
plt.grid(True)
plt.show()

3)

3-5 top100 순위변화표 만들기

song_pivot = pd.pivot_table(data=song, index="date", columns = "title", values = "rank")
song_pivot.head()

3-6 엑셀 만들기

song_pivot.to_excel("../data/03.song_pivot.xlsx")
#만약 multi index잡혀 있을시 이 옵션 사용하기 
song_pivot.columns = song_pivot.columns.droplevel()

3-7 top100 타겟음원 5곡 순위변화표 만들기

#한글설정
import platform
import seaborn as sns
from matplotlib import font_manager,rc

path = "C:/Windows/Fonts/malgun.ttf"

if platform.system() == "Darwin":
    rc("font",family="Arial Unicode MS")
elif platform.system() == "Windows":
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc("font", family = font_name)
else:
    print("Unknown system.sorry")
target_col = ["Say My Name","After LIKE","ANTIFRAGILE","Anti-Hero","Butter"]
plt.figure(figsize=(20,8))
plt.title("날짜별 순위")
plt.xlabel("날짜")
plt.ylabel("순위")
plt.xticks(rotation="vertical")
plt.tick_params(bottom="off", labelbottom="off")#밑에 tick부분 - 선생겨서 구분자
plt.plot(song_pivot[target_col])
plt.legend(target_col,loc="best")
plt.grid(True)
plt.show()

Memo

01. url

:다음영화경우는 url값만 주어도 크롤링이 되었는데 멜론의 경우는 406error코드가 떠서 UserAgent로 해결했음! 벅스는 확인안해봤지만 만약을 데뷔해 멜론코드로 진행

url = "https://movie.daum.net/ranking/reservation"
response = urlopen(url)
# print(f"http상태: {response.status}")
soup = BeautifulSoup(response, "html.parser")
print(soup.prettify())
url = "https://music.bugs.co.kr/chart/track/realtime/total?chartdate=20230517"
ua = UserAgent()
ua.ie

req = Request(url, headers={"user-agent" : ua.ie})
response = urlopen(req)
soup = BeautifulSoup(response,"html.parser")
print(soup.prettify())

[참고1] 크롤링 거부
: https://coffee-with-me.tistory.com/12
[참고2] HTTP 트랜잭션과 요청/응답 헤더(request/response header)
:https://ltvw.tistory.com/entry/HTTP-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EA%B3%BC-%EC%9A%94%EC%B2%AD%EC%9D%91%EB%8B%B5-%ED%97%A4%EB%8D%94requestresponse-header

  • 이글은 제로베이스 데이터 취업 스쿨의 강의자료 일부를 발췌하여 작성되었음.
profile
데이터와 이미지로 세상을 공부하는 중입니다 :)

0개의 댓글