본문 바로가기
사이드 프로젝트/음악추천 챗봇 서비스

음악추천챗봇3.2 데이터 수집 및 처리-Track정보

by 카프리썬_ 2021. 5. 31.
728x90

어떤 데이터를 수집할 것인가?

이번엔 NoSQL에 저장할 데이터를 수집해볼 것이다. 

그래서 일단 가장 간단하게 '노래정보'를 얻어보려고 한다. 

이때 검색을 위해 Artist API를 쓸 수 있는데, 대신 아티스트ID로 검색할 수 있다. 

>> Artist API 레퍼런스 https://developer.spotify.com/documentation/web-api/reference/#endpoint-get-an-artist

Aritist's Top Tracks 정보

request형식을 살펴보면 

  • header : token을 가진 auth
  • path파라미터: id
  • 쿼리파라미터 : maket

주의해야할 점은 이전에 search api와 다르게 id는조금 특이하게 path파라미터가 있다.

그래서 직접 parameter로 매개변수를 넣는게 아니라

endpoint뒤에 파라미터id를 직접 넣어야한다. 

    endpoint = "https://api.spotify.com/v1/artists/{}/top-tracks".format(artist_id)

maket은 쿼리파라미터이다. 

그리고 국가코드인데, 스포티파이가 국제서비스인만큼 top track이 국가기준으로 다른가보다. 

그래서 특정 국가 기준으로 top track 정보를 response한다.  

    query_params = {'market':'KR'}

 	artist_t=requests.get(endpoint,params=query_params,headers=headers)
    artist_tr=json.loads(artist_t.text)

API 테스트 >>
https://developer.spotify.com/console/get-artist-top-tracks/?country=SE&id=43ZHCT0cAZBISjO8DG9PnE

 

respone 값은 이전에 search api와 비슷하다. 

얻을 수 있는 실질적인 정보가 items안에 들어있다. 

 

참고로, limit을 정할 수가 없다. 그래서 해당하는 track이 엄청 많이 나온다.

키만 뽑아봐도...정말 너무 많다.....여기에서 어떤 데이터를 가지고 올지가 관건일것 같다 

    artist_track = Artist.top_tracks(id,headers)['tracks']
    for item in artist_track:
        print(item.keys())
        
dict_keys(
['album', 'artists', 'disc_number',
'duration_ms', 'explicit', 'external_ids', 'external_urls',
'href', 'id', 'is_local', 'is_playable', 
'name', 'popularity', 'preview_url',
'track_number', 'type', 'uri'])

이전에 searchAPI는 이런 키들을 직접 RDB의 속성으로 넣었는데 이번엔 NoSQL로 저장해볼 생각이다. 

그 이유는 속성을 일일이 RDB에 넣을수도 있을지 의심스러웠기 때문이다. 뭔가 굉장히 번거로울 것 같은 느낌이 든다.

또 만약에 SQL을 날린다고 해도, 불필요한 속성까지 검새하게 된다면 비효율적일 것 같았다. 

 

너무 많으니까 분량상 하나의 트랙정보에 대해서만 가져와봤다. 

데이터구조를 파악하기에 약간 복잡하다..

{
   "tracks":[
      {
         "album":{
            "album_type":"single",
            "artists":[
               {
                  "external_urls":{
                     "spotify":"https://open.spotify.com/artist/3Nrfpe0tUJi4K4DXYWgMUX"
                  },
                  "href":"https://api.spotify.com/v1/artists/3Nrfpe0tUJi4K4DXYWgMUX",
                  "id":"3Nrfpe0tUJi4K4DXYWgMUX",
                  "name":"BTS",
                  "type":"artist",
                  "uri":"spotify:artist:3Nrfpe0tUJi4K4DXYWgMUX"
               }
            ],
            "external_urls":{
               "spotify":"https://open.spotify.com/album/2BDhPi2XCYujYxU6VM0QaD"
            },
            "href":"https://api.spotify.com/v1/albums/2BDhPi2XCYujYxU6VM0QaD",
            "id":"2BDhPi2XCYujYxU6VM0QaD",
            "images":[
               {
                  "height":640,
                  "url":"https://i.scdn.co/image/ab67616d0000b273ed656680374294d5217193fa",
                  "width":640
               },
               {
                  "height":300,
                  "url":"https://i.scdn.co/image/ab67616d00001e02ed656680374294d5217193fa",
                  "width":300
               },
               {
                  "height":64,
                  "url":"https://i.scdn.co/image/ab67616d00004851ed656680374294d5217193fa",
                  "width":64
               }
            ],
            "name":"Butter",
            "release_date":"2021-05-21",
            "release_date_precision":"day",
            "total_tracks":2,
            "type":"album",
            "uri":"spotify:album:2BDhPi2XCYujYxU6VM0QaD"
         },
         "artists":[
            {
               "external_urls":{
                  "spotify":"https://open.spotify.com/artist/3Nrfpe0tUJi4K4DXYWgMUX"
               },
               "href":"https://api.spotify.com/v1/artists/3Nrfpe0tUJi4K4DXYWgMUX",
               "id":"3Nrfpe0tUJi4K4DXYWgMUX",
               "name":"BTS",
               "type":"artist",
               "uri":"spotify:artist:3Nrfpe0tUJi4K4DXYWgMUX"
            }
         ],
         "disc_number":1,
         "duration_ms":164441,
         "explicit":false,
         "external_ids":{
            "isrc":"QM6MZ2156864"
         },
         "external_urls":{
            "spotify":"https://open.spotify.com/track/3VqeTFIvhxu3DIe4eZVzGq"
         },
         "href":"https://api.spotify.com/v1/tracks/3VqeTFIvhxu3DIe4eZVzGq",
         "id":"3VqeTFIvhxu3DIe4eZVzGq",
         "is_local":false,
         "is_playable":true,
         "name":"Butter",
         "popularity":98,
         "preview_url":"https://p.scdn.co/mp3-preview/edf24f427483d886b640c5ed9944f9291e0976fc?cid=c87e807943a1483883faaaa881aa43ef",
         "track_number":1,
         "type":"track",
         "uri":"spotify:track:3VqeTFIvhxu3DIe4eZVzGq"
      },

다시한번 보니 NoSQL을 선택해야하만 하는 이유가 보였다.

데이터구조를 테이블을 어떻게 설계할지 난감했던 이유가 있었다.

각 속성마다 타입도 제각각이고, 또 세부적인 속성이 너무 많다. 그래서 너무 많아보였다. 

ablum은 {}안에 앨범타입, 아티스트, 앨범id, 이미지, 앨범이름 등등이 있고, 

그 안에 속하는 아티스트의 경우 또 아티스트id, 아티스트url, 아티스트명이 있다. 

 

또한, 아티스트id가 검색을 하는 key가 될 수 있을 것 같다. 

아마 아티스트id에 해당하는 여러개의 track들이 나오겠지. 

 

이런 구조때문에 RDB는 불가능할것이라고 보고 NoSQL로 설계해보기로 했다.


데이터를 어떻게 저장 할 것인가?

이걸 바탕으로 Track에 대한 데이터구조를 설계할 수 있다. 

NoSQL이기 때문에 JSON형식 그대로 넣으면 된다. 

 

AWS DyanmoDB

위와 같이 설계한 테이블을 RDS에서 또는 로컬DB를 통해 생성하는 작업이 필요하다.

그리고 설게한 테이블에 API를 통해 수집한 데이터를 저장하는 작업도 필요하다. 

 


왜 NoSQL로 저장하는가?

지난 RDB일떄도 기록했던 이야기이다.

어떤 DB를 사용할 것인지에 대한 기준을 배울 수 있었다. 

  1. 유저의 측면 : 누가 이 데이터를 사용할 것인가?
  2. 서비스의 측면 : 어떻게 데이터를 활용할 것인가?

위 두가지에 따라서 데이터를 어디에 저장하고, 어떻게 가공할 것인지가 결정될 수 있다.

 

느낌적인 느낌으로 NoSQL을 선택했지만, NoSQL로 저장하는게 유용한 기준이다.

  • 서비스확장 가능성에 있어 데이터확장성이 좋은 경우
  • 데이터 요청시속도 및 유연성이 좋은 경우 -> Artist id를 파티션키로 지정함으로써 데이터검색속도UP

또한 RDB에 비해 아래와 같은 장점도 가지고 있다.

  • 다른 데이터를 활용할 가능성에 대비해 최대한 많은 데이터를 저장할 수 있다
  • 많은 데이터들 중에서 원하는 데이터만 추출하여 사용가능하다 

이를 고려했을떄 TOP RECORD response를 NoSQL로 저장한 이유는 

최대한 많은 데이터를 저장하기 위해서이다. 

그리고 각 속성별 타입들이 제각각이고, JSON형식이라 이대로를 유지하는게 더 검색하기 편할것 같았다.

 

 

출처 

https://snepbnt.tistory.com/132?category=784758

반응형