使用Flask调用Spotify API时出现无访问令牌错误求助
解决Flask调用Spotify API获取用户热门歌曲的错误
1. 检查授权Scope是否包含user-top-read
Spotify的/me/top/tracks接口必须要求**user-top-read**权限才能访问。如果你的授权流程未请求该scope,API会返回权限不足的错误(当前异常捕获逻辑可能掩盖了具体信息,导致显示None, reason: None)。
修改授权请求代码,确保scope参数包含user-top-read:
scope = "user-top-read user-read-private user-read-email" # 在生成授权URL时传入该scope auth_url = sp_oauth.get_authorize_url(scope)
2. 完善错误捕获与调试信息
当前仅捕获SpotifyException,但token无效、API返回非预期结构等其他错误也会导致问题。扩展错误捕获逻辑,打印更详细的错误细节:
try: top_tracks_response = sp.current_user_top_tracks(limit=10, offset=0, time_range='short_term') # 先验证响应结构是否符合预期 if 'items' in top_tracks_response: top_tracks = top_tracks_response['items'] else: print("API响应无'items'字段:", top_tracks_response) top_tracks = [] except spotipy.SpotifyException as e: print("Spotify API错误详情:", e.http_status, e.code, e.msg) except Exception as e: print("其他错误:", str(e))
通过这种方式可以明确错误类型,比如401(token过期/无效)、403(权限不足)等。
3. 验证Token的有效性与权限
调用Spotify的/me接口验证token是否有效,同时确认权限是否正确:
try: user_info = sp.current_user() print("当前授权用户:", user_info['display_name']) except Exception as e: print("Token验证失败:", str(e))
如果这一步也失败,说明token无效或过期,需要检查get_token()函数的刷新逻辑。
4. 修复Token获取与刷新逻辑
确保get_token()能正确返回未过期的有效token,包含自动刷新逻辑:
def get_token(): token_info = sp_oauth.get_cached_token() if not token_info or sp_oauth.is_token_expired(token_info): # 刷新过期的token token_info = sp_oauth.refresh_access_token(token_info['refresh_token']) return token_info
5. 修复代码潜在问题
初始化top_tracks为默认值,避免获取失败时后续代码报错,同时完善数据传递到模板的逻辑:
@app.route('/top-songs') def top_songs(): token_info = get_token() if not token_info: return "授权失败,请重新登录" access_token = token_info['access_token'] sp = spotipy.Spotify(auth=access_token) top_tracks = [] # 初始化默认值,防止后续报错 try: top_tracks_response = sp.current_user_top_tracks(limit=10, offset=0, time_range='short_term') if 'items' in top_tracks_response: top_tracks = top_tracks_response['items'] else: print("API响应异常:", top_tracks_response) except spotipy.SpotifyException as e: print("Spotify API错误:", e.http_status, e.msg) except Exception as e: print("未知错误:", str(e)) # 提取歌曲关键信息,传递给模板 track_data = [ { 'name': track['name'], 'artist': track['artists'][0]['name'], 'album': track['album']['name'] } for track in top_tracks ] return render_template('index.html', tracks=track_data)
内容的提问来源于stack exchange,提问作者christian fasole
相关产品推荐
相关产品推荐

