Spotify 음악 크롤링 중 마주한 문제들과 이를 해결한 과정

2025. 3. 21. 17:06·SPRINGBOOT/음악 스트리밍 서비스

📌 프로젝트 배경

 

음악 스트리밍 프로젝트 ‘MiTi’에서는 사용자의 취향에 맞는 음악을 추천하기 위해 Spotify API를 이용한 음악 데이터 크롤링이 필요했습니다. 크롤링 과정에서 다양한 문제들이 발생했고, 이를 해결하며 기능의 완성도를 높일 수 있었습니다.

 

spotify는 다른 플랫폼과는 달리 저작권이나 보안 문제를 책임지지 않아도 되고,

특히 맞춤형 추천 기능이 주 기능인 저희 웹서비스에서는 추천 알고리즘을 중요하게 생각했기 때문에, 음악의 특성(danceability, energy 등)을 자세히 가져올 수 있어 해당 api를 선택하기로 결정했습니다.


client_credentials_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret)

sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

csv_file_path = "spotify_tracks.csv"

chart_tracks = sp.playlist_tracks('37i9dQZEVXbMDoHDwVN2tF') #트랙 인기차트 id

with open(csv_file_path, 'w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    # 헤더
    writer.writerow([
        "id", "music_name", "music_id", "music_popularity", "album_image", "album_detail",
        "music_artist_name", "music_artist_id", "music_artist_popular", "music_genre", 
        "music_artist_genres", "music_artist_followers", "music_analysis_url", 
        "music_key", "music_duration_ms", "music_instrumentalness", "music_acousticness", 
        "music_danceability", "music_energy", "music_liveness", "music_loudness", 
        "music_mode", "music_speechiness", "music_tempo", "music_time_signature", 
        "music_valence", "music_track_href", "music_type", "music_uri"
    ])
    
    # 트랙마다 음악 정보 작성
    track_id = 1

    for track in chart_tracks['items']:
        track_info = track['track']
        album_id = track_info['album']['id']
        album_tracks = sp.album_tracks(album_id)['items']

        for album_track in album_tracks:
            # 개별 트랙의 상세 정보
            track_details = sp.track(album_track['id'])

            # 오디오 특징
            audio_features = sp.audio_features(album_track['id'])[0]
            
            # 아티스트 정보
            artist_names = []
            artist_ids = []
            artist_popularities = []
            artist_genres = []
            artist_followers = []

            for artist in album_track['artists']:
                artist_id = artist['id']
                artist_info = sp.artist(artist_id)
                artist_names.append(artist_info['name'])
                artist_ids.append(artist_info['id'])
                artist_popularities.append(artist_info['popularity'])
                artist_genres.append(', '.join(artist_info['genres']))
                artist_followers.append(artist_info['followers']['total'])

            # 행 작성
            writer.writerow([
                track_id, album_track['name'], album_track['id'], 
                track_details['popularity'],  # 개별 트랙의 인기도 가져오기
                track_info['album']['images'][0]['url'], track_info['album']['name'],
                ', '.join(artist_names), ', '.join(artist_ids), ', '.join(map(str, artist_popularities)),
                ', '.join(artist_names), ', '.join(artist_genres), ', '.join(map(str, artist_followers)),
                audio_features['analysis_url'], audio_features['key'], 
                audio_features['duration_ms'], audio_features['instrumentalness'],
                audio_features['acousticness'], audio_features['danceability'], 
                audio_features['energy'], audio_features['liveness'], 
                audio_features['loudness'], audio_features['mode'], 
                audio_features['speechiness'], audio_features['tempo'], 
                audio_features['time_signature'], audio_features['valence'], 
                audio_features['track_href'], audio_features['type'], album_track['uri']
            ])
            track_id += 1  # ID 값 증가

 

위 코드는 초기에 작성한 코드로, 인기차트의 id를 직접 삽입해 해당 차트에 담겨있는 음악들의 정보를 가져왔습니다.

가장 간단한 방법이기 때문에 오류 발생률이 적고, 빠르게 정보 수집이 가능하다는 장점이 있었지만, 여러 가지 문제점도 많이 발생했습니다.


 

❗ 크롤링 중 마주한 문제점과 해결 방법

 

 

1. 수동으로 음악 ID를 하나씩 검색해야 해 시간이 과도하게 소요됨

  • 문제점      수동으로 ID를 가져오다 보니 크롤링 범위가 제한되고, 자동화가 어렵고 비효율적이었음
  • 해결 방법  Spotify의 카테고리 정보를 활용해 자동으로 플레이리스트를 탐색하는 방식으로 전환
  • 사용 코드 
# Spotify에서 제공하는 카테고리 가져오기
categories = sp.categories(limit=50)  # 최대 50개의 카테고리 가져오기
for category in categories['categories']['items']:
	category_id = category['id']
    print(f"Fetching playlists from category: {category['name']}")

    # 카테고리별 플레이리스트 가져오기 (최대 20개)
    playlists = sp.category_playlists(category_id=category_id, limit=20)  # 각 카테고리당 20개의 플레이리스트
    for playlist in playlists['playlists']['items']:
    	playlist_id = playlist['id']
        playlist_name = playlist['name']
        print(f"Fetching tracks from playlist: {playlist_name}")

        # 플레이리스트에서 트랙 가져오기
        offset = 0
        limit = 50  # 트랙을 50개씩 가져오기
        total_tracks = sp.playlist_tracks(playlist_id, limit=1)['total']  # 전체 트랙 수 확인

 

2. 서로 다른 플레이리스트 간에 음악이 중복 저장됨

  • 문제점      동일한 음악이 여러 플레이리스트에 포함되어 중복 데이터가 누적됨
  • 해결 방법  음악 제목 기준으로 중복 여부를 검사한 후 저장
  • 사용 코드 
if music_name in recorded_music_names:
	continue

 

 

3. 특정 음악은 국내(KR)에서 재생이 불가능함

  • 문제점      재생이 불가능한 음악까지 수집되어 실제 사용자 재생 시 오류 발생 우려
  • 해결 방법  available_markets 필드에 KR이 포함되어 있는 음악만 수집
  • 사용 코드 
if track_info.get('is_playable', True) and 'KR' in track_info.get('available_markets', []):

 

 

4. 과도한 API 요청으로 Spotify API 호출 제한이 발생함

  • 문제점      크롤링 범위가 넓어지며 일정 시간 후 API 호출 제한에 도달
  • 해결 방법  카테고리 수, 플레이리스트 수, 트랙 수를 제한하고 요청 간 딜레이를 적용
  • 사용 코드 
time.sleep(REQUEST_DELAY)

 

✅ 마무리하며

 

이번 크롤링 작업을 통해 API 사용 시의 유의점과 효율적인 데이터 수집 방식에 대해 배울 수 있었습니다.

특히 단순히 데이터를 가져오는 것뿐 아니라, 서비스 환경에서 실제로 사용할 수 있는 데이터를 선별하고 처리하는 능력이 중요하다는 점을 실감했습니다.

 

 

👉 전체 코드 보러 가기

👉 크롤링한 데이터를 이용한 추천 알고리즘 설계 및 리팩터링 과정 보러 가기

'SPRINGBOOT > 음악 스트리밍 서비스' 카테고리의 다른 글

사용자 취향 반영을 위한 음악 추천 알고리즘 개선 과정  (0) 2025.03.25
'SPRINGBOOT/음악 스트리밍 서비스' 카테고리의 다른 글
  • 사용자 취향 반영을 위한 음악 추천 알고리즘 개선 과정
bogyeom
bogyeom
백엔드 개발자 준비중
  • bogyeom
    딩코링코
    bogyeom
  • 전체
    오늘
    어제
    • 분류 전체보기 (10)
      • Node.js (0)
        • 크리스마스 미니홈피 (0)
      • SPRINGBOOT (2)
        • 음악 스트리밍 서비스 (2)
        • 식당 추천 서비스 (0)
      • 우아한 테크코스 프리코스 (3)
      • 알고리즘 오답노트 (5)
        • JAVA (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
bogyeom
Spotify 음악 크롤링 중 마주한 문제들과 이를 해결한 과정
상단으로

티스토리툴바