내일배움단 3주차 과제 풀이

노트북이 뭐 한 것도 없는데 버벅거린다… 램을 4+4+4로 박을걸 그랬나;;

아니 근데 그때는 8기가도 널럴했음 지금이야 씁 에반데 하지만.


문제

지니뮤직 차트에서 1~50위까지 순위, 곡명, 가수 크롤링하는 게 문제인데 문제가 하나 있다.제시한 URL이 2020년 4월 3일 차트여…

아니 지금 2022년인뎁쇼. 그래서 어제자 차트로 변경했음.

풀이

import requests
from bs4 import BeautifulSoup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=D&rtm=N&ymd=20220627',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
print(soup)

일단 여기까지 하면 뭐가 많이 나온다. 정상이니 속행하자.

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
print(trs)

그리고 이렇게 넣어주면 선택이 된다. 참고로 원래 selector에는 tr:nth-child로 되어 있는데 그거 그대로 붙여넣기 하면 에러뜬다. 리퀘스트인지 뷰티풀수프인지 아무튼 nth-child를 지원 안 하기 때문에 굳이 난 nth-child 포기 못해! 그러면 nth-of-type로 바꿔주자.

for tr in trs:
    rank = tr.select_one('td.number').text
    print(rank)

랭크를 가져올건데… 난 랭크가 궁금하지 상승하강은 안 궁금하다. 그럼 [:2]로 슬라이싱을 할건데(이거나 [0:2]나 같은거) 그렇게만 했더니 공백이 어마무시하잖음? 그래서 .strip()이 들어가는거다. sys.stdin.readline()의 친구기도 한 이녀석은 공백 떼뿌라!!! 모드거든… 그래서 힌트에 strip()이 있었던거다. 

for tr in trs:
    rank = tr.select_one('td.number').text[:2].strip()
    print(rank)

공백 떼뿌라!!!

어디가요 다른거 가져와야지.

for tr in trs:
    rank = tr.select_one('td.number').text[:2].strip()
    title = tr.select_one('td.info > a').text.strip()
    print(rank,title)

이놈들 제목에 뭔 공백이 이렇게 많아…

for tr in trs:
    rank = tr.select_one('td.number').text[:2].strip()
    title = tr.select_one('td.info > a').text.strip()
    artist = tr.select_one('td.info > a.artist').text
    print(rank,title,artist)

가수명은 의외로 공백이 없다. 응? 저게 다냐고? 네.

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=D&rtm=N&ymd=20220627',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
#body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.number
for tr in trs:
    rank = tr.select_one('td.number').text[:2].strip()
    title = tr.select_one('td.info > a').text.strip()
    artist = tr.select_one('td.info > a.artist').text
    print('{} {} {}'.format(rank,title,artist))

진짜로 이게 다다.

import requests
from bs4 import BeautifulSoup
import pandas as pd

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/genre?ditc=D&ymd=20220627&genrecode=M0400',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
#body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.number
rank_list = []
title_list = []
artist_list = []
for tr in trs:
    rank = tr.select_one('td.number').text[:2].strip()
    title = tr.select_one('td.info > a.title.ellipsis').text.strip()
    artist = tr.select_one('td.info > a.artist.ellipsis').text.strip()
    rank_list.append(rank)
    title_list.append(title)
    artist_list.append(artist)
rank_df = pd.DataFrame({"순위": rank_list, "곡명":title_list,"가수":artist_list})
rank_df  = rank_df.set_index('순위')
print(rank_df)

판다스… 멕이지 말자…

참고로 판다스쪽 URL은 J-pop 차트이다. 저거 썡으로 복붙해서 하면 일본어가 반긴다고? 아니 J-pop 차트니까 그렇지. 이것도 예전… 그러니까 싸이월드로 나는 가끔 눈물을 흘린다 이럴 때는 J-pop 있지도 않았는데(그래서 일마존에서 샀다…) 요즘은 멜론이나 지니뮤직, 벅스, 네이버 바이브에서 판매하는 것도 있다. 물론 다 파는 건 아님. 

본인은 애니 오프닝 위주로 듣지만, 요즘은 우리나라 아이돌들이 일본쪽 애니 오프닝을 부르기도 한다. 대표적인 예가 TxT(투모로우바이투게더)가 부른 Force(월드 트리거 오프닝), 동방신기가 부른 share the world(였나? 원피스 오프닝), 보아도 페어리테일 오프닝 하나 불렀었고 최근에는 킹스레이드 애니 오프닝을 드림캐처가(Eclipse), 신의 탑 애니메이션 오프닝을 스트레이 키즈(TOP, 국문 일문 있음)가 부르기도 했다. 

이런 거 보면 참 격세지감일세…