๐ŸŽง Spotify API ๋‹ค๋ฃจ๊ธฐ -(2)

์„œ์€์„œยท2023๋…„ 9์›” 7์ผ

๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„ ๋งŒ๋“ค๊ธฐ

์•จ๋ฒ” ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

๋จผ์ € 2020์— ๋ฐœ๋งค๋œ ์Œ์•…ํŠธ๋ž™์˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.

์ฝ”๋“œ

result = sp.search(q='year:2020', type='track', limit=5, offset=1)

๊ฒฐ๊ณผ

์ด ๋•Œ 2020 ๋ฐœ๋งค๋œ ์•จ๋ฒ”์— ๋Œ€ํ•œ ์‹ค์งˆ์ ์ธ ์ •๋ณด๋Š” โ€˜track โ†’ itemsโ€™์˜ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

  • album โ†’ uri : ์•จ๋ฒ”์— ๋Œ€ํ•œ uri๋กœ sp.album(uri)๋ฅผ ์ด์šฉํ•ด์„œ ์•จ๋ฒ”์˜ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
    • ์ด ๋•Œ ์–ป์€ ์•จ๋ฒ”์˜ ์ •๋ณด๋ฅผ album_info๋ผ๊ณ  ํ•˜๊ฒ ๋‹ค.
  • album_info โ†’ track โ†’ items : ์•จ๋ฒ”์— ๋“ค์–ด์žˆ๋Š” ๋ชจ๋“  track๋“ค์ด ๋“ค์–ด์žˆ๋‹ค. ์ด๋Š” ํ•˜๋‚˜๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ณ , ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ๋  ์ˆ˜ ๋„ ์žˆ๋‹ค. ๋•Œ๋ฌธ์— ๋ฆฌ์ŠคํŠธ์— ๊ณก ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ• ๊ฑฐ ๊ฐ™๋‹ค!
    <track์—์„œ ํ•„์š”ํ•œ ์ •๋ณด>
    - name : ๊ณก ์ œ๋ชฉ
    - track_number : ์•จ๋ฒ” ๋‚ด ํŠธ๋ž™์ˆœ์„œ
    - id : ๊ณก์˜ id
    - url : ๊ณก ์ •๋ณด๊ฐ€ ์žˆ๋Š” url (๊ฐ€์‚ฌ๋ฅผ ๋”ฐ์˜ค๊ธฐ ์œ„ํ•จ)
    - audio_features : ๊ณก์˜ audio_features

์ตœ์ข… ์ฝ”๋“œ ์˜ˆ์‹œ (2020๋…„) โ†’ ์•„์ง audio_features๋Š” ๋ฏธ๋ฐ˜์˜

artist_name =[]
artist_id =[]
song = []

for i in range(0,1000,50):
    track_results = sp.search(q='year:2020', type='track', limit=50, offset=i)
    for i, t in enumerate(track_results['tracks']['items']):
        album_uri = t['album']['uri']
        album_info = sp.album(album_uri)
        artist_name.append(album_info['artists'][0]['name'])
        artist_id.append(album_info['artists'][0]['id'])
        artist_song = []
        for j in range(len(album_info['tracks']['items'])):
            name = album_info['tracks']['items'][j]['name']
            track_number = album_info['tracks']['items'][j]['track_number']
            id = album_info['tracks']['items'][j]['id']
            audio_feature = sp.audio_features(id)
            url = album_info['tracks']['items'][j]['external_urls']['spotify']
            artist_song.append({'name':name,'track_number':track_number,'id':id,'url':url,'audio_feature':audio_feature})
        song.append(artist_song)

artist_name

artist_id

song

๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„ ์ƒ์„ฑํ•˜๊ธฐ

song_2020 = pd.DataFrame([artist_id,artist_name,song],index=['Id','Artist','Song']).T
print(song_2020.head())
song_2020.to_excel('song_2020.xlsx')

๊ฒฐ๊ณผ

2020 - 2023๊นŒ์ง€ ๊ณก ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ–ˆ๋‹ค!!

Audio_feature ์ถ”์ถœํ•˜๊ธฐ

์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด audio_feature๋ฅผ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

sp.audio_features('track id์ž…๋ ฅ')

๐Ÿ“ย excel ๋ถˆ๋Ÿฌ์™€ DataFrame ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •

 song_2020 = pd.read_excel('song_2020.xlsx',index_col=0)
 song_2020.head()

  type(song_2020['Song']) # pandas.core.series.Series

โ€˜Songโ€™ ์—ด์— ๋“ค์–ด์žˆ๋Š” ๋ฐ์ดํ„ฐ๋Š” to_excel()์˜ ๊ณผ์ •์„ ๊ฑฐ์น  ๋•Œ String์œผ๋กœ ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๋‹ค์‹œ ๋ฆฌ์ŠคํŠธ๋กœ ๋งŒ๋“ค์–ด์•ผํ•œ๋‹ค.

pickle์„ ์ด์šฉํ•ด์„œ ์ €์žฅํ•˜๋ฉด ๋ฆฌ์ŠคํŠธ์˜ ํ˜•ํƒœ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๋‹ค์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ธฐ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ๋ฟ๋”๋Ÿฌ ์ค‘๊ฐ„์— API ํ• ๋‹นํ–ฅ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์„œ ์–ด์ฉ” ์ˆ˜ ์—†์ด ๊ธฐ์กด ํŒŒ์ผ์„ ์ด์šฉํ•ด์•ผํ–ˆ์Œ
โ†’ ast.literal_eval()์„ ์ด์šฉํ•ด String์„ List๋กœ ๋ณ€ํ™˜์‹œํ‚จ๋‹ค.

    import ast
    def to_list(x):
        return ast.literal_eval(x)
    song_2020['Song'] = song_2020['Song'].apply(to_list)

์ด๋•Œ ์ธ๋ฑ์Šค๋Š” ์•จ๋ฒ”์„ ๋œปํ•˜๋ฉฐ ๋ฆฌ์ŠคํŠธ ์•ˆ์— ๋“ค์–ด์žˆ๋Š” ๊ฒƒ์€ ์•จ๋ฒ”์•ˆ์— ์ˆ˜๋ก๋œ ํŠธ๋ž™(๊ณก)๋“ค ์ด๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ณก๋“ค์˜ id๋ฅผ ์ด์šฉํ•ด audio_features๋ฅผ ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ด๋‹ค.

์ด๋•Œ song_2020[โ€™Songโ€™]์˜ ์ธ๋ฑ์Šค๋Š” ์•จ๋ฒ”์„ ๋œปํ•˜๋ฉฐ ๋ฆฌ์ŠคํŠธ ์•ˆ์— ๋“ค์–ด์žˆ๋Š” ๊ฒƒ์€ ์•จ๋ฒ”์•ˆ์— ์ˆ˜๋ก๋œ ํŠธ๋ž™(๊ณก)๋“ค ์ด๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ณก๋“ค์˜ id๋ฅผ ์ด์šฉํ•ด audio_features๋ฅผ ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ด๋‹ค. ๋ฐ˜๋ณต๋ฌธ์„ ํ†ตํ•ด ํ”ผ์ณ๋“ค์„ ์ถ”์ถœํ•ด์˜จ๋‹ค.

2021,2022,2023 ํŒŒ์ผ๋„ ๋˜‘๊ฐ™์ด ์ง„ํ–‰ ํ•  ๊ฒƒ์ด๋‹ค.

# track๋งˆ๋‹ค id ์ถ”์ถœ
audio_features_id= []
for i in song_2020['Song']:
    id_list = []
    for j in i:
        id = j['id']
        id_list .append(id)
    audio_features_id.append(id_list)

๐Ÿšจย ๋น„์ƒ!!(ํ•ด๊ฒฐ!)

API ํ• ๋Ÿ‰๋‹น์˜ ๋ถ€์กฑ์œผ๋กœ audio_features๋“ค์„ ์ถ”์ถœํ•˜๋‹ค๊ฐ€ ์ค‘๊ฐ„์— ๋Š๊ธฐ๋Š” ์‚ฌ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋‹ค์–‘ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ๋Š”๋ฐ ์ด๋ฏธ ์˜ค๋Š˜ ํ• ๋‹น๋Ÿ‰์„ ๋‹ค ์จ๋ฒ„๋ ค์„œ ๊ฐฑ์‹ ์ด ๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ์ด ํ•ด๊ฒฐ์ฑ…๋“ค์„ ์‹œ๋„ํ•ด๋ณผ ์ˆ˜ ์žˆ์„๋“ฏ ์‹ถ๋‹คโ€ฆใ… ใ…œใ…œใ… ใ…œใ… ใ…œ

๐Ÿ”—ย ํ•ด๊ฒฐ์ฑ…

Rate Limits | Spotify for Developers
์œ„์˜ ํŽ˜์ด์ง€๋ฅผ ๋“ค์–ด๊ฐ€๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ๊ตฌ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

โ–ถ๏ธŽ Spotify API๋Š” API์˜ ์•ˆ์ •์„ฑ์„ ์œ ์ง€ํ•˜๊ณ ์ž ์†๋„์ œํ•œ์„ ๋‘๊ณ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

Spotify์˜ API ์†๋„ ์ œํ•œ์€ 30์ดˆ ๋™์•ˆ ์•ฑ์ด Spotify์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•œ ํ˜ธ์ถœ ์ˆ˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐ๋˜๋ฉฐ, ์•ฑ์ด ์•ฑ์˜ ์†๋„ ์ œํ•œ์„ ์ดˆ๊ณผํ•˜๋ฉด Spotify์˜ ์›น API์—์„œ 429 ์˜ค๋ฅ˜ ์‘๋‹ต์ด ํ‘œ์‹œ๋œ๋‹ค.(๋‚ด๊ฐ€ ๋งž์ดํ–ˆ๋˜ ๊ทธ ์˜ค๋ฅ˜!)

๋•Œ๋ฌธ์— ์†๋„ ์ œํ•œ์— ์—ผ๋‘๋ฅผ ๋‘๊ณ  ์•ฑ์„ ๋นŒ๋“œํ•ด์•ผํ•œ๋‹ค!!!

๐Ÿ’ก๋‚ด๊ฐ€ ์‹œ๋„ํ•œ ๋ฐฉ๋ฒ•

1๏ธโƒฃ ํ™•์žฅ ํ• ๋‹น๋Ÿ‰ ๋ชจ๋“œ ์‹ ์ฒญ
์ด ๋ชจ๋“œ์˜ ์•ฑ์—๋Š” ์ƒˆ ์•ฑ์˜ ๊ธฐ๋ณธ ๋ชจ๋“œ์ธ ๊ฐœ๋ฐœ ๋ชจ๋“œ์˜ ์•ฑ๋ณด๋‹ค ํ›จ์”ฌ ๋†’์€ ์†๋„ ์ œํ•œ์ด ์žˆ๋‹ค. ์ด๋ฅผ ์‹ ์ฒญํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Spotify์˜ ํ—ˆ๊ฐ€๋ฅผ ๋ฐ›์•„์•ผํ•˜๋Š”๊ฒŒ ๋‚˜์—๊ฒŒ๋Š” ์ด ๊ณผ์ •์ด ์–ด๋ ค์› ๋‹คโ€ฆ
โ†’ ์ด ๋ฐฉ๋ฒ•์€ ๋‚˜ ๊ฐ™์ด ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•ด API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค๋ณด๋‹ค๋Š” ์ง„์งœ ์•ฑ์„ ๋งŒ๋“ค ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋” ํ•„์š”ํ•  ๊ฑฐ ๊ฐ™๋‹ค.(์Šน์ธ ์ค‘๊ฐ„ ๊ณผ์ •์— ์•ฑ์˜ ๊ตฌ์ฒด์ ์ธ ์‚ฌ์ง„์„ ์ฒจ๋ถ€ํ•˜๋ผ๋Š” ์งˆ๋ฌธ์ด ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ!)

2๏ธโƒฃ ๋ฐฐ์น˜ API ํ™œ์šฉ
Spotify ์—๋Š” ํ•˜๋‚˜์˜ API ์š”์ฒญ์œผ๋กœ ์ผ๊ด„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š”ย Get Multiple Albumsย ์—”๋“œํฌ์ธํŠธ ์™€ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ API๊ฐ€ ์žˆ๋‹ค. audio_feature๋Š” track id๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด id ๋ณ„ audio_feature๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

  • id ๋ฆฌ์ŠคํŠธ
  • id๋ณ„ audio_feature

๐Ÿ’กย ๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด ํ• ๋‹น๋Ÿ‰์„ ๋ชจ๋‘ ์ฑ„์šฐ์ง€ ์•Š๊ณ  audio_feature๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์—ˆ๋‹ค!

  • audio_feature ์ˆ˜์ง‘ ์ฝ”๋“œ
song_2022 = pd.read_excel('song_2022.xlsx',index_col=0)
song_2022['Song'] = song_2022['Song'].apply(to_list)

audio_features_id= []
for i in song_2022['Song']:
    id_list = []
    for j in i:
        id = j['id']
        id_list .append(id)
    audio_features_id.append(id_list)

audio_features_2022 = []
count = 0
for i in audio_features_id:
    print('count : {}'.format(count))
    feature = sp.audio_features(i)
    audio_features_2022.append(feature)
    count += 1
profile
๋‚ด์ผ์˜ ๋‚˜๋Š” ์˜ค๋Š˜๋ณด๋‹ค ๋” ๋‚˜์•„์ง€๊ธฐ๋ฅผ :D

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2023๋…„ 11์›” 25์ผ

์ž˜ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋Š”๋ฐ ํ˜น์‹œ error detection code ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ 429 error ๋œจ์…จ๋‚˜์š”?

except spotipy.SpotifyException as e:

    # Handle Spotify API exceptions
    print(f"Spotify API Exception: {e}")
except Exception as e:
    # Handle other exceptions or errors
    print(f"Error: {e}")

SpotifyException ์ฒ˜๋ฆฌํ•ด์คฌ๋Š”๋ฐ๋„ 429error๋„ ์•ˆ ๋œจ๊ณ  *์ƒํƒœ๋กœ search๋ถ€๋ถ„์—์„œ ๋ง‰ํžˆ๋„ค์š”.. token ์‹œ๊ฐ„๋„ ํ™•์ธํ–ˆ๋Š”๋ฐ ๋งŒ๋ฃŒ๋œ ๊ฑด ์•„๋‹ˆ๋ผ ๋ญ๊ฐ€ ๋ฌธ์ œ์ธ์ง€ ํ˜น์‹œ ์•„์‹œ๋Š” ๊ฒŒ ์žˆ์„๊นŒ ์‹ถ์–ด ๋Œ“๊ธ€ ๋‚จ๊น๋‹ˆ๋‹ค.

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ