调用Spotify API获取当前播放歌曲时返回404错误,求解决方案
问题根源
你遇到的404错误本质是授权方式错误。当前使用的client_credentials授权流属于应用级授权,不关联任何具体Spotify用户,而/me/player/currently-playing这类/me开头的端点需要访问已授权用户的个人数据,因此API会返回404(实际是权限不足,Spotify部分场景下用404替代403)。
解决步骤
1. 切换到Authorization Code Flow(带PKCE)
该流程会引导用户登录Spotify并授权你的应用,获取包含用户上下文的access token,才能访问用户相关的API端点。
2. 申请必要的权限(Scopes)
在Spotify开发者后台配置应用时,需添加以下权限:
user-read-currently-playing:允许获取当前播放的歌曲playlist-modify-public或playlist-modify-private:根据你的播放列表是公开/私有选择,用于添加歌曲到播放列表
3. 修改Token获取逻辑
以下是带PKCE的Authorization Code Flow示例代码:
import base64 import hashlib import random import string from urllib.parse import urlencode import requests import json # 生成PKCE所需的code verifier和challenge def generate_pkce_code_verifier(length=128): chars = string.ascii_uppercase + string.ascii_lowercase + string.digits + "-._~" return ''.join(random.choice(chars) for _ in range(length)) def generate_pkce_code_challenge(verifier): sha256 = hashlib.sha256(verifier.encode('utf-8')).digest() return base64.urlsafe_b64encode(sha256).decode('utf-8').rstrip('=') # 第一步:获取授权码 def get_authorization_code(client_id, redirect_uri): code_verifier = generate_pkce_code_verifier() code_challenge = generate_pkce_code_challenge(code_verifier) auth_url = "https://accounts.spotify.com/authorize" params = { "client_id": client_id, "response_type": "code", "redirect_uri": redirect_uri, "scope": "user-read-currently-playing playlist-modify-private", # 根据需求调整scope "code_challenge_method": "S256", "code_challenge": code_challenge } # 引导用户访问该URL,授权后跳转至redirect_uri并携带code参数 print(f"请访问以下URL授权:{auth_url}?{urlencode(params)}") # 本地测试需手动获取跳转后的code(桌面应用可监听本地端口自动获取) authorization_code = input("请输入授权后的code:") return authorization_code, code_verifier # 第二步:用授权码交换access token def get_token_with_code(client_id, redirect_uri, authorization_code, code_verifier): url = "https://accounts.spotify.com/api/token" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "authorization_code", "code": authorization_code, "redirect_uri": redirect_uri, "client_id": client_id, "code_verifier": code_verifier } result = requests.post(url, headers=headers, data=data) json_result = json.loads(result.content) return json_result["access_token"], json_result["refresh_token"]
4. 调整现有函数的容错处理
原代码直接访问json_result["item"]["uri"]可能引发KeyError(比如用户未播放歌曲时item字段不存在),同时需确保添加歌曲的请求参数格式正确:
def get_current_track_and_post_in_playlist(token): headers = {"Authorization": "Bearer " + token} result = requests.get('https://api.spotify.com/v1/me/player/currently-playing', headers=headers) if result.status_code != 200: print(f"请求失败:{result.status_code}") print(result.json()) return json_result = result.json() if not json_result.get("item"): print("当前没有播放歌曲") return track_uri = json_result["item"]["uri"] playlist_id = "0p4d0akcszc87kcf0pym6qws1" # 添加歌曲到播放列表,uris参数需为数组格式 add_track_url = f'https://api.spotify.com/v1/playlists/{playlist_id}/tracks' data = {"uris": [track_uri]} playlist_response = requests.post(add_track_url, headers=headers, json=data) if playlist_response.status_code == 201: print("歌曲成功添加到播放列表") else: print(f"添加失败:{playlist_response.status_code}") print(playlist_response.json())
注意事项
- 在Spotify开发者后台正确配置
redirect_uri,本地测试可使用http://localhost:8888/callback这类地址 - 长期运行的应用需用
refresh_token定期刷新access token,避免过期 - 处理API返回的错误状态码,不要直接解析响应内容,先判断请求是否成功
内容的提问来源于stack exchange,提问作者kolokasi
相关产品推荐
相关产品推荐

