我有一些 Python 代码来制作一个 Flask 应用程序,它可以自动将我所有每周发现的歌曲保存到播放列表中,但它无法找到每周发现的歌曲。我让它列出了我的所有其他播放列表,它们显示得很好,我已手动关注 Spotify 中的发现每周播放列表,但它不会显示。
编辑:有人建议检查最大限制,但对我来说至少这并不适用,因为默认限制是 50,我有 41 个播放列表(包括每周发现)
def save_discover_weekly(token_info):
sp = spotipy.Spotify(auth=token_info['access_token'])
cur_playlists = sp.current_user_playlists()['items']
discover_weekly_id = None
saved_weekly_id = None
for playlist in cur_playlists:
print(playlist['name'])
if playlist['name'] == 'Discover Weekly':
discover_weekly_id = playlist['id']
print(discover_weekly_id)
break
if playlist['name'] == 'Saved Weekly':
saved_weekly_id = playlist['id']
print(saved_weekly_id)
if discover_weekly_id is None:
return "Discover Weekly not found"
if not saved_weekly_id:
print("Creating saved weekly playlist")
saved_weekly = sp.user_playlist_create(sp.current_user()['id'],
"Saved Weekly", True)
saved_weekly_id = saved_weekly['id']
discover_weekly_songs = sp.playlist_items(discover_weekly_id)
song_uris = [song['track']['uri'] for song in discover_weekly_songs['items']]
sp.user_playlist_add_tracks(sp.current_user()['id'], saved_weekly_id,
song_uris)
return "Discover Weekly songs saved to Saved Weekly playlist!"
许多
Spotify
端点使用 pagination 并采用一对参数:offset
和 limit
。如果跳过,则采用默认值,这些值通常记录在相应的端点参考中。例如,当前用户的播放列表请求的默认限制为 20。
spotipy
遵循这种方式,有时使用不同的默认值。例如,current_user_playlist
的默认限制为 50:
def current_user_playlists(self, limit=50, offset=0):
""" Get current user playlists without required getting his profile
Parameters:
- limit - the number of items to return
- offset - the index of the first item to return
"""
return self._get("me/playlists", limit=limit, offset=offset)
因此,对于拥有大量播放列表的用户来说,有可能无法检索足够的数据来获取所需的播放列表。您需要逐页请求这些播放列表:
MAX_LIMIT = 50
MAX_OFFSET = 100000
DISCOVER_WEEKLY = "Discover Weekly"
SPOTIFY_USER_ID = 'spotify'
def get_discover_weekly_playlist(spotify: spotipy.Spotify) -> Optional[dict]:
for offset in range(0, MAX_OFFSET + 1, MAX_LIMIT):
try:
response = spotify.current_user_playlists(limit=MAX_LIMIT,
offset=offset)
except spotipy.SpotifyException:
break
try:
playlists = response['items']
except (TypeError, KeyError):
break
if not playlists:
break
for playlist in playlists:
if (playlist['owner']['id'] == SPOTIFY_USER_ID
and playlist['name'] == DISCOVER_WEEKLY):
# playlist found doesn't have tracks
# have to request the full data by id
return spotify.playlist(playlist['id'])
return None
考虑到边界情况,可能存在浏览播放列表比简单搜索更差的情况。通过查询“Discover Weekly”,搜索结果中似乎没有那么多公开播放列表。 Spotify 的排名也很高。它实际上可能是结果集合中的第一个播放列表。上面关于分页的所有内容仍然适用于这里:
MAX_LIMIT = 50
MAX_OFFSET = 1000
DISCOVER_WEEKLY_QUERY = "Discover Weekly"
PLAYLIST_TYPE = 'playlist'
SPOTIFY_USER_ID = 'spotify'
def get_discover_weekly(spotify: spotipy.Spotify) -> Optional[dict]:
for offset in range(0, MAX_OFFSET + 1, MAX_LIMIT):
try:
response = spotify.search(q=DISCOVER_WEEKLY_QUERY, type=PLAYLIST_TYPE,
offset=offset, limit=MAX_LIMIT)
except spotipy.SpotifyException:
break
try:
playlists = response['playlists']['items']
except (TypeError, KeyError):
break
if not playlists:
break
for playlist in playlists:
if (playlist['owner']['id'] == SPOTIFY_USER_ID
and playlist['name'] == DISCOVER_WEEKLY_QUERY):
# same here, item found doesn't have tracks
# have to request the full data by id
return spotify.playlist(playlist['id'])
return None