使用Spotify API创建播放列表时持续出现403 Forbidden错误求助
问题分析
你遇到的403 Forbidden错误核心原因是授权模式不对:
- 你当前用的
client_credentials(客户端凭证)授权模式,只能获取访问Spotify公开数据的权限,无法对用户个人账号(比如创建播放列表、修改个人收藏)进行操作。 - 而Spotify测试网站能创建播放列表,是因为它使用了用户授权后的token,带有操作个人数据的权限。
解决步骤
要创建用户个人播放列表,必须改用Authorization Code Flow授权模式,这是Spotify API中用于操作用户私有数据的标准流程。
1. 准备工作(Spotify开发者后台)
- 登录你的Spotify开发者账号,进入对应应用的设置页面
- 在
Redirect URIs中添加一个本地重定向地址,比如http://localhost:8080(后续代码会用到) - 确认应用的
Client ID和Client Secret已保存
2. 修改授权流程代码
替换原来的access_token函数,实现Authorization Code Flow:
import json import requests from bs4 import BeautifulSoup from urllib.parse import urlencode import webbrowser from http.server import HTTPServer, BaseHTTPRequestHandler # 全局变量 CLIENT_ID = '你的Client ID' CLIENT_SECRET = '你的Client Secret' REDIRECT_URI = 'http://localhost:8080' SPOTIFY_EP = 'https://api.spotify.com/v1/' AUTHORIZE_URL = 'https://accounts.spotify.com/authorize' TOKEN_URL = 'https://accounts.spotify.com/api/token' ACCESS_TOKEN = '' # 处理重定向获取授权码 class AuthHandler(BaseHTTPRequestHandler): def do_GET(self): global ACCESS_TOKEN # 提取授权码 auth_code = self.path.split('code=')[1].split('&')[0] # 用授权码换访问token token_data = { 'grant_type': 'authorization_code', 'code': auth_code, 'redirect_uri': REDIRECT_URI, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET } token_response = requests.post(TOKEN_URL, data=token_data) token_response.raise_for_status() token_json = token_response.json() ACCESS_TOKEN = token_json['access_token'] # 返回成功提示 self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(b'Authorization successful! You can close this window now.') # 关闭服务器 self.server.shutdown() def get_authorized_token(): # 请求授权,需要playlist-modify-public权限 auth_params = { 'client_id': CLIENT_ID, 'response_type': 'code', 'redirect_uri': REDIRECT_URI, 'scope': 'playlist-modify-public' # 创建公开播放列表需要的权限,私有则用playlist-modify-private } auth_url = f"{AUTHORIZE_URL}?{urlencode(auth_params)}" # 打开浏览器让用户授权 webbrowser.open(auth_url) # 启动本地服务器接收重定向 server = HTTPServer(('localhost', 8080), AuthHandler) server.serve_forever() # 获取授权后的token get_authorized_token()
3. 修复创建播放列表的代码
原来的create_playlist函数有两个问题:
- 发送数据时没有用JSON格式(requests的
data参数传字典会默认表单编码,而Spotify API要求JSON) - 不需要在请求数据里加
grant_type
修改后的函数:
def create_playlist(user_id='shakuryonsteward'): playlist_url = f"{SPOTIFY_EP}users/{user_id}/playlists" payload = { 'name': "Top 100 Tracks from Birthday", 'description': "Generated API Playlist as part of Coding Project xP", 'public': True } headers = { 'Authorization': f'Bearer {ACCESS_TOKEN}', 'Content-Type': 'application/json' } # 用json参数自动序列化并设置正确的Content-Type response = requests.post(playlist_url, json=payload, headers=headers) response.raise_for_status() print("播放列表创建成功:", response.json()) return response.json()['id'] # 返回播放列表ID,后续可以用来添加歌曲 # 创建播放列表 playlist_id = create_playlist()
4. 补充:添加歌曲到播放列表
如果需要把之前获取的歌曲添加到新播放列表,可以用这个函数:
def add_tracks_to_playlist(playlist_id, track_uris): add_url = f"{SPOTIFY_EP}playlists/{playlist_id}/tracks" payload = { 'uris': track_uris } headers = { 'Authorization': f'Bearer {ACCESS_TOKEN}', 'Content-Type': 'application/json' } response = requests.post(add_url, json=payload, headers=headers) response.raise_for_status() print("歌曲添加成功") # 示例:如果之前的spotify_search函数正常,调用它获取歌曲URI后添加 # top100_tracks = spotify_search(ACCESS_TOKEN) # add_tracks_to_playlist(playlist_id, top100_tracks)
关键注意点
- 权限范围:根据播放列表是公开还是私有,选择
playlist-modify-public或playlist-modify-private,多个权限用空格分隔 - Token有效期:Authorization Code Flow的访问token会过期,需要用返回的
refresh_token刷新,避免重复授权(可以自行添加刷新逻辑) - 请求格式:所有操作用户数据的POST/PUT请求,必须用JSON格式发送数据,不能用表单编码
内容的提问来源于stack exchange,提问作者Shakuryon Steward
相关产品推荐
相关产品推荐

