为何无法免费使用Spotify Web API?Python调用API获取公开播放列表遇403 Forbidden问题求助
我刚好遇到过类似的情况,先给你梳理下问题根源和解决办法:
为什么你用Client Credentials Flow会返回403?
你当前用的是client_credentials授权方式,这种方式是无用户上下文的——简单说就是你的应用直接以自己的身份请求API,不需要用户登录。但Spotify在最近的权限调整中,收紧了这种授权模式的访问范围:
- 之前免费开发者账号用这个模式能访问公开播放列表、搜索等端点,但现在只有关联了Premium账号的应用,才能用Client Credentials Flow访问这些内容;
- 对于普通免费开发者账号,无用户上下文的请求只能访问有限的基础端点(比如获取艺术家的基本信息),而播放列表曲目、搜索这类操作,必须要有用户(哪怕是免费用户)的授权上下文。
那些旧教程能正常用,大概率是因为当时Spotify还没做这个权限限制。
适合你场景的解决方案:切换到Authorization Code Flow
既然你的用户不一定有Premium,那必须改用授权码流(Authorization Code Flow)——这个模式需要用户登录自己的Spotify账号(免费账号也完全可以),获取带有用户授权上下文的token,这样就能正常访问公开播放列表、搜索等端点了。
修改后的代码示例
首先你得先去Spotify开发者控制台,给你的应用添加一个重定向URI(比如http://localhost:8080/callback,随便填一个能访问的本地地址就行),然后替换下面的代码:
import os import base64 from requests import post, get import json from urllib.parse import urlencode # 替换成你自己的客户端信息 client_id = "你的客户端ID" client_secret = "你的客户端密钥" redirect_uri = "http://localhost:8080/callback" # 要和开发者控制台设置的一致 def generate_auth_url(): # 定义需要的权限范围,这里只请求读取公开播放列表的权限 auth_params = { "client_id": client_id, "response_type": "code", "redirect_uri": redirect_uri, "scope": "playlist-read-public" } return "https://accounts.spotify.com/authorize?" + urlencode(auth_params) def get_access_token(auth_code): auth_string = f"{client_id}:{client_secret}" auth_bytes = auth_string.encode("utf-8") auth_base64 = str(base64.b64encode(auth_bytes), "utf-8") url = "https://accounts.spotify.com/api/token" headers = { "Authorization": f"Basic {auth_base64}", "Content-Type": "application/x-www-form-urlencoded" } data = { "grant_type": "authorization_code", "code": auth_code, "redirect_uri": redirect_uri } response = post(url, headers=headers, data=data) json_response = json.loads(response.content) return json_response["access_token"] def get_auth_header(token): return {"Authorization": f"Bearer {token}"} def fetch_playlist_tracks(token, playlist_id): url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks" headers = get_auth_header(token) response = get(url, headers=headers) if response.status_code == 200: return json.loads(response.content) else: print(f"请求出错:状态码 {response.status_code}") print(response.json()) return None # 步骤1:生成授权链接,让用户访问并授权 auth_url = generate_auth_url() print(f"请打开下面的链接,登录你的Spotify账号并授权:\n{auth_url}") # 步骤2:用户授权后,从浏览器地址栏里复制code参数 auth_code = input("请粘贴授权后地址栏里的code:") # 步骤3:用code换取访问token access_token = get_access_token(auth_code) # 步骤4:调用API获取播放列表内容 playlist_data = fetch_playlist_tracks(access_token, "021tegZzZnT8YEpLr0lC3V") if playlist_data: print("\n播放列表内容:") print(json.dumps(playlist_data, indent=2))
几个关键注意点
- 权限范围(Scope):如果你的应用需要更多功能,比如搜索艺术家,可以添加
user-read-recently-played或playlist-read-collaborative等权限,具体看Spotify API文档里的端点要求; - 免费用户兼容:授权码流完全支持免费Spotify用户,只要用户愿意授权你的应用,就能正常访问公开内容;
- 重定向URI:必须和你在开发者控制台设置的完全一致,否则会出现授权失败的情况。
额外建议
如果你的应用是面向前端的(比如网页App),建议用Authorization Code Flow with PKCE,这种模式不需要在前端暴露客户端密钥,安全性更高。
内容的提问来源于stack exchange,提问作者skinnyleonard




