如何修复Spotipy缓存错误并访问他人创建的Spotify播放列表?
问题解决:Spotify播放列表/专辑转Markdown表格脚本优化
一、缓存错误修复
报错Couldn't read/write token to cache at: .cache是因为Spotipy默认在当前工作目录创建.cache文件存储访问令牌,主目录下通常没有写入权限导致的。
解决方法:初始化SpotifyClientCredentials时直接禁用缓存(ClientCredentials模式下令牌有效期短,重新获取开销可忽略):
# 禁用缓存,避免权限问题 sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials( client_id=client_id, client_secret=client_secret, cache_path=None # 关键:禁用缓存 ))
二、访问他人公开播放列表修复
原代码仅获取播放列表的第一页数据(默认20条),无法完整获取他人公开播放列表的所有歌曲。同时数据提取逻辑重复,易出错。
解决方法:循环分页获取所有歌曲,统一处理播放列表和专辑的track数据结构:
if 'playlist' in uri: results = sp.playlist_tracks(uri) tracks = results['items'] # 循环获取分页数据 while results['next']: results = sp.next(results) tracks.extend(results['items']) elif 'album' in uri: album_tracks = sp.album_tracks(uri) tracks = album_tracks['items'] # 专辑也可能分页,同样处理 while album_tracks['next']: album_tracks = sp.next(album_tracks) tracks.extend(album_tracks['items'])
同时简化数据提取逻辑,避免重复判断:
# 统一处理track对象:播放列表的item里是track字段,专辑直接是track对象 track_obj = track['track'] if 'track' in track else track song_name = track_obj['name'] artist_name = track_obj['artists'][0]['name'] album_name = track_obj['album']['name'] duration_ms = track_obj['duration_ms']
完整修改后的代码
import spotipy from spotipy.oauth2 import SpotifyClientCredentials def get_song_details(uri): client_id = 'your_client_id_here' client_secret = 'your_client_secret_here' # 初始化Spotify客户端,禁用缓存避免权限问题 sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials( client_id=client_id, client_secret=client_secret, cache_path=None )) tracks = [] if 'playlist' in uri: results = sp.playlist_tracks(uri) tracks = results['items'] # 分页获取所有播放列表歌曲 while results['next']: results = sp.next(results) tracks.extend(results['items']) elif 'album' in uri: album_tracks = sp.album_tracks(uri) tracks = album_tracks['items'] # 分页获取所有专辑歌曲 while album_tracks['next']: album_tracks = sp.next(album_tracks) tracks.extend(album_tracks['items']) else: print("Invalid link. Please provide a valid Spotify playlist or album link.") return "" table = "| Song | Artist | Album | Length |\n| --- | --- | --- | --- |\n" for track in tracks: # 统一提取track对象 track_obj = track['track'] if 'track' in track else track song_name = track_obj['name'] artist_name = track_obj['artists'][0]['name'] album_name = track_obj['album']['name'] duration_ms = track_obj['duration_ms'] duration_min_sec = divmod(duration_ms // 1000, 60) length = f"{duration_min_sec[0]:02}:{duration_min_sec[1]:02}" table += f"| {song_name} | {artist_name} | {album_name} | {length} |\n" return table uri = input("Enter a Spotify playlist or album link: ") output_table = get_song_details(uri) print(output_table)
关键修改说明
- 禁用缓存:通过
cache_path=None彻底解决无写入权限目录下的缓存报错。 - 分页获取全部歌曲:循环调用
sp.next()获取所有分页数据,确保不会遗漏歌曲。 - 统一数据提取逻辑:简化track对象的判断,避免重复代码,保证播放列表和专辑数据处理一致。
内容的提问来源于stack exchange,提问作者arcana
相关产品推荐
相关产品推荐

