본문 바로가기
[python]데이터 분석/[python]웹 스크랩핑(scraping)

[Web scraping]멜론 TOP100 차트(2/2)

by 코드몽규 2022. 2. 9.
반응형

지난 시간에는 멜론 TOP 100 차트 페이지에서 1위부터 100위까지의

곡명, 가수, 앨범, 발매일, 장르 등 상세 정보를 가져와 리스트화 까지 끝냈다. 

 

오늘은 만들어낸 리스트를 JSON파일로 만들어서 아래의 작업을 해보려고 한다.

1. json 파일을 load 하여 Pandas의 DataFrame에 저장하기

2. DataFrame 객체를 DB의 Table에 저장하기

 


먼저 JSON 파일로 저장해보자

 

import json

#with open(파일명,쓰기모드,인코딩) as file:
with open('data/songs.json','w',encoding='utf-8') as file:
	json.dump(song_detail_list, file)

EX) with open json.dump()

import json
with open("student_file.json", "w") as json_file:
    json.dump(student_data, json_file)


with open(): json.dump()를 사용해서 JSON 포맷 데이터를 디스크에 쓰기

with open("student_file.json", "w")로 "student_file.json" 이름의 파일을 쓰기("w") 모드로 열어놓고, json.dump(student_data, json_file)로직렬 화해서 JSON으로 내보내고자 하는 객체 student_data를, 직렬화된 데이터가 쓰일 파일 json_file에 쓰기를 해주었습니다. 

 

저장한 파일을 읽어보자 

with open('data/songs.json',encoding='utf-8') as file:
    song_json = json.loads(file.read())

print(song_json)

출력된 결과가 너무 방대하니까 생략하겠다!

대신 len으로 갯수를 세어보면 올바르게 출력되었는지 알 수 있다.

100개에 대한 정보를 저장했으니 100이 나오면 올바른 것이다.


json파일로 load 했으니 이제 pandas의 DateFrame객체 사용해보자 

1. 우선 json파일이 없다는 가정하에 song_detail_list만 갖고 만들어보자

# song_detail_list을 읽어서 dataframe 객체를 생성하는 방법
# dataframe 객체를 생성
import pandas as pd


song_df2 = pd.DataFrame(columns=['곡명','가수','앨범','발매일','장르','좋아요','가사'])
#1개의 row = Series 객체, 1개의 column = Series 객체
#즉 1개의 열과 행은 series객체 -> 이게 모이면 dataframe
for song_detail in song_detail_list:
    #print(type(song_detail), song_detail)
    series_obj = pd.Series(song_detail)
    song_df2 = song_df2.append(series_obj, ignore_index=True)

song_df2.head()
# song_df2

 

song_detail_list에서  dataframe을 만들 칼럼을 하나하나씩 설정해주고 

series_obj = pd.series(song_detail)로 해당 열에 해당하는 행을 하나씩 출력하여 더해주는 식으로 만들어보았다.

 


 

2. 두 번째로 저장한 JSON파일을 활용해서 dataframe을 만들어보자

import pandas as pd

song_df = pd.read_json('data/songs.json')
print(type(song_df))
song_df.head()

더 간편하게 이전과 똑같은 dataframe을 만들었다.

그럼 우리는 이렇게 만든 dataframe으로 어떤 작업을 할 수 있을까??

 


  • 칼럼 별로 조회를 할 수 있다.

1. 가수의 칼럼 값을 선택해서 칼럼의 값 별로 row counting 

song_df['가수'].head()
print((type(song_df['가수']))) # 가수라는 컬럼만 선택했기 때문에 이에 해당하는 행 1개만 나옴 /serises

song_df['가수'].value_counts() # 1~100위 차트에 '가수'가 부른 노래가 몇개인지 알 수 있다.

2. 장르의 컬럼값을 선택해서 컬럼의 값별로 row counting

song_df['장르'].value_counts() #1~100위중 어떤 장르의곡이 몇개 있는지 파악가능

3. unique()을 통해 중복제거

song_df['가수'].unique() #1~100위까지 어떤 가수가 있는지 파악가능
song_df['장르'].unique() #1~100위까지 어떤 장르가 있는지 파악가능

특정 행과 열을 선택하기

  • loc[], iloc[] 사용한다.
       * Slicing 을 사용해서 구간을 주어서 행과 열을 선택
        * [ ]
        * (list)를 사용해서 여러개의 행과 열을 선택
        * 조건식을 만족하는 행과 열을 선택

1. slicing : 인덱스가 0부터 5까지의 모든 행과 열을 선택하기

song_df.loc[:5]

2. slicing : 인덱스가 0부터 10까지의 모든 행과 열을 선택하기, 1개의 행을 skip

song_df.loc[:10:2] #기본[0:10:1,:]

3. slicing : 인덱스가 0부터 10까지의 모든 행과 곡명부터 장르까지의 열을 선택하기 

song_df.loc[0:10,'곡명':'장르']

4. 여러개의 행과 열을 선택하는 경우

song_df.loc[:10:2,['곡명','장르']] #[[행],[열]]
song_df.loc[:10,['발매일','가수']] #[[행],[열]]
song_df.loc[[1,5,9],['발매일','가수']] #[[행],[열]]

# 10부터 20까지의 행과 곡명, 가수, 좋아요 열을 선택 

song_df.loc[10:20,['곡명','가수','좋아요']]

5. 특정 열만 출력하는 함수 

#가수가 '임영웅'인 곡명에서 좋아요까지 행과 열 출력
def get_song(singer):
    return song_df.loc[song_df['가수'] == singer, '곡명':'좋아요']
get_song('임영웅')


#장르가 댄스인 곡명과 좋아요까지의 행과 열 출력
def get_song(word):
    return song_df.loc[song_df['장르'] == word, '곡명':'좋아요']

get_song('댄스')

6. 평균보다 높은 행을 선택 

like_avg = song_df['좋아요'].mean()
#print(like_avg)

print('like max',song_df['좋아요'].max()) #좋아요 수가 가장많은 수
print('like min',song_df['좋아요'].min()) #좋아요 수가 가장적은 수
print('like median',song_df['좋아요'].median()) #좋아요 수의 중앙값



# 좋아요 수를 가장많이 받은 곡에 대한 정보
like_max =song_df['좋아요'].max()
song_df.loc[song_df['좋아요'] == like_max]

song_df.loc[song_df['좋아요'] == like_max]

7. 응용

#좋아요 수가 평균보다 높은 행과 곡명,가수,좋아요 열을 선택

like_avg = song_df['좋아요'].mean()

#reset_index(drop=True) 를 통해 순서를 다시 세운다.
song_df.loc[song_df['좋아요'] >= like_avg, ['곡명','가수','좋아요']].reset_index(drop=True)


#좋아요 수가 평균보다 높은 행과 곡명,가수,좋아요 열을 선택하고 좋아요 건수가 높은 순서대로 정렬하고 index reset 해주자
song_df.loc[song_df['좋아요'] >= like_avg, ['곡명','가수','좋아요']].sort_values(by='좋아요',ascending=False).reset_index(drop=True)
반응형

댓글