我想用 spotipy library 从 spotify 上所有我喜欢的歌曲制作一个播放列表

I want to make a playlist from all my liked songs on spotify with spotipy library

因为我喜欢的歌曲不是 public 我希望 spotipy 从所有歌曲中获取一个列表并将它们添加到我的播放列表中,但是当我尝试使用循环执行此操作时它说 uri不正确,我不知道是否应该使用其他方法。

client_credentials_manager = SpotifyClientCredentials(client_id=cid, client_secret=secret)
scope = 'user-library-read playlist-modify-public'
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager,auth_manager=SpotifyOAuth(scope=scope))
def show_tracks(results):
    for item in results['items']:
        track = item['track']
        #print("%32.32s %s" % (track['artists'][0]['name'], track['name']))
        sp.playlist_add_items(playlist_id, track['uri'])

results = sp.current_user_saved_tracks()
show_tracks(results)

while results['next']:
    results = sp.next(results)
    show_tracks(results)

错误是

HTTP Error for POST to https://api.spotify.com/v1/playlists/5ZzsovDgANZfiXgRrwq5fw/tracks returned 400 due to Invalid track uri: spotify:track:s
Traceback (most recent call last):
  File "C:\Users\ferch\AppData\Local\Programs\Python\Python37\lib\site-packages\spotipy\client.py", line 245, in _internal_call
    response.raise_for_status()
  File "C:\Users\ferch\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\models.py", line 941, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://api.spotify.com/v1/playlists/5ZzsovDgANZfiXgRrwq5fw/tracks

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "make_playlists.py", line 23, in <module>
    show_tracks(results)
  File "make_playlists.py", line 20, in show_tracks
    sp.playlist_add_items(playlist_id, track['uri'])
  File "C:\Users\ferch\AppData\Local\Programs\Python\Python37\lib\site-packages\spotipy\client.py", line 1025, in playlist_add_items
    position=position,
  File "C:\Users\ferch\AppData\Local\Programs\Python\Python37\lib\site-packages\spotipy\client.py", line 296, in _post
    return self._internal_call("POST", url, payload, kwargs)
  File "C:\Users\ferch\AppData\Local\Programs\Python\Python37\lib\site-packages\spotipy\client.py", line 266, in _internal_call
    headers=response.headers,
spotipy.exceptions.SpotifyException: http status: 400, code:-1 - https://api.spotify.com/v1/playlists/5ZzsovDgANZfiXgRrwq5fw/tracks:
 Invalid track uri: spotify:track:s, reason: None

我认为这个问题是因为track的变量类型['uri']

playlist_add_items 期望将 URI、URL 或 ID 列表添加到播放列表,但现在您传递的是单个 URI,它是这样的字符串:spotify:track:2t7rS8BHF5TmnBR5PmnnSU . spotipy 库的代码可能会执行循环 for item in items...,因此当您向它传递一个字符串时,它会将字符串中的每个字符视为不同的项目。所以它遇到第一个字符 s 并尝试从中创建一个 URI,结果是 spotify:track:s。这不是有效的 URI,因此请求失败。

您可以尝试将 uri 包装在一个列表中,如下所示:

for item in results['items']:
        track = item['track']
        # Note brackets around track['uri']
        sp.playlist_add_items(playlist_id, [track['uri']])  

这将解决您现在遇到的问题,但您可能会在为要添加到播放列表的每个曲目发出一个请求时遇到问题。你可以 运行 变成 rate limiting issues, so I recommend trying to build a list of 100 URIs at a time, which is the max that can be sent in one request.

牢记这一点,我们可以尝试这样的事情:

def show_tracks(results):
    for idx in range(0, len(results['items']), 100):
         uris = [item['track']['uri'] for item in results['items'][idx:idx+100]]
         sp.playlist_add_items(playlist_id, uris)

另一种方法是创建一个列表,其中包含您要添加的所有 uris/ids 曲目,然后将该列表传递给 sp.playlist_add_items() 函数。如果您再次需要 uris 列表,这可能会很有用。像这样:

uris = []        

for item in results['items']:
    track = item['track']
    uris.append(track['uri'])

sp.playlist_add_items(playlist_id, uris)

请记住,sp.playlist_add_items 一次只能添加 <= 100 首曲目。我创建了这个循环来处理添加曲目列表,无论大小:(其中 songIDs 是歌曲 ID / uris 的列表)

i = 0
increment = 99
while i < len(songIDS)+increment:
    try:
        sp.playlist_add_items(playlistID, songIDS[i: i+increment])
    except spotipy.exceptions.SpotifyException:
        pass

    i += increment

希望这对您有所帮助,我自己只使用了一个星期的 spotipy