有人知道为什么我使用下面的代码从Spotify播放列表中删除曲目时会收到403吗?
注意:下面的代码中已经去掉了client_id、client_secret、username和playlist_id的声明。
# Number of songs to delete from the playlist
num_songs_to_delete = 5 # Change this to the desired number
# Encode client_id and client_secret for authentication
client_creds = f"{client_id}:{client_secret}"
#client_creds_b64 = base64.b64encode(client_creds.encode()).decode()
client_creds_b64 = base64.b64encode('{}:{}'.format(client_id, client_secret).encode())
# Get access token using client credentials flow
token_url = "https://accounts.spotify.com/api/token"
token_data = {
"grant_type": "client_credentials"
}
#token_headers = {
# "Authorization": f"Basic {client_creds_b64}"
#}
token_headers = {"Authorization": "Basic {}".format(client_creds_b64.decode())}
token_response = requests.post(token_url, data=token_data, headers=token_headers)
token_response_data = token_response.json()
access_token = token_response_data['access_token']
# Get playlist tracks using the access token
playlist_url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
playlist_headers = {
"Authorization": f"Bearer {access_token}"
}
playlist_response = requests.get(playlist_url, headers=playlist_headers)
playlist_data = playlist_response.json()
# Sort tracks by their added_at timestamp in descending order
tracks = playlist_data['items']
sorted_tracks = sorted(tracks, key=lambda x: x['added_at'], reverse=True)
# Extract track URIs
tracks_uris = [track['track']['uri'] for track in sorted_tracks]
# Delete the specified number of tracks from the playlist
tracks_to_delete = tracks_uris[:min(num_songs_to_delete, len(tracks_uris))]
# Delete tracks
delete_url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
delete_data = {
"tracks": [{"uri": uri} for uri in tracks_to_delete]
}
delete_response = requests.delete(delete_url, headers=playlist_headers, data=json.dumps(delete_data))
print(delete_response)
if delete_response.status_code == 200:
print(f"{num_songs_to_delete} songs deleted from the playlist.")
else:
print("Failed to delete songs from the playlist.")
我尝试使用requests和spotipy这两个库来连接Spotify的网络接口,想写一个程序来从指定的播放列表中删除歌曲,但运行代码时总是出现403错误。我的client_id和client_secret与开发者门户中的应用信息是匹配的。我查了很多资料,但还是找不到问题的根源。而且我的应用在Spotify开发者门户中创建得也没问题。
非常感谢任何帮助!
2 个回答
两个原因
#1 客户端凭证流程无法删除播放列表
你使用了 "grant_type": "client_credentials"
来获取访问令牌。
你应该使用 授权码流程。
如果你查看Spotify的API文档,在“移除播放列表项目”部分,
https://developer.spotify.com/documentation/web-api/reference/remove-tracks-playlist
你可以看到 授权范围
。这意味着你的访问令牌是通过 授权码流程
获取的。
这意味着你需要运行本地服务器来处理重定向(回调)URL。
spotipy 可以很方便地为你提供帮助。
#2 [范围]很重要
如果你查看Spotify的范围文档,
https://developer.spotify.com/documentation/web-api/concepts/scopes
这两个范围是移除播放列表曲目所必需的。
playlist-modify-public
playlist-modify-private
我修改了你的代码,并添加了 spotipy
的代码。
保存为 demo.py
import requests
import json
import spotipy
from spotipy.oauth2 import SpotifyOAuth
client_id = '<your client id>'
client_secret = '<your client secret>'
redirect_uri = '<your redirect uri>' # get from developer dash board
username = '<your user name>' # get from user profile
SCOPEs = ['playlist-modify-private', 'playlist-modify-public']
playlist_id = '<your playlist ID>' # You want to delete from this playlist ID
# Number of songs to delete from the playlist
num_songs_to_delete = 5 # Change this to the desired number
auth_manager = SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=SCOPEs, username=username)
sp = spotipy.Spotify(auth_manager=auth_manager)
token_info = sp.auth_manager.get_cached_token()
access_token = None
if (token_info is None):
access_token = sp.auth_manager.get_access_token()
else:
access_token = token_info['access_token']
# Get playlist tracks using the access token
playlist_url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
playlist_headers = {
"Authorization": f"Bearer {access_token}"
}
playlist_response = requests.get(playlist_url, headers=playlist_headers)
playlist_data = playlist_response.json()
# Sort tracks by their added_at timestamp in descending order
tracks = playlist_data['items']
sorted_tracks = sorted(tracks, key=lambda x: x['added_at'], reverse=True)
# Extract track URIs
tracks_uris = [track['track']['uri'] for track in sorted_tracks]
# Delete the specified number of tracks from the playlist
tracks_to_delete = tracks_uris[:min(num_songs_to_delete, len(tracks_uris))]
# Delete tracks
delete_url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
delete_data = {
"tracks": [{"uri": uri} for uri in tracks_to_delete]
}
delete_response = requests.delete(delete_url, headers=playlist_headers, data=json.dumps(delete_data))
print(delete_response)
if delete_response.status_code == 200:
print(f"{num_songs_to_delete} songs deleted from the playlist.")
else:
print("Failed to delete songs from the playlist.")
如何获取
client_id
、client_secret
和 redirect_uri
通过浏览器打开这个网址
https://developer.spotify.com/dashboard
如何获取用户名
通过浏览器打开这个网址
https://open.spotify.com/
安装依赖
pip install requests
pip install spotipy
运行之前
检查你的播放列表中的歌曲数量,运行前要有9首歌。
运行它
python demo.py
运行后
由于移除了5首歌,剩下4首歌。
总结
我只是演示了如何从播放列表中移除歌曲,但我使用了混合的API调用,既请求了API又使用了Spotipy API。如果你使用 授权码流程
,我建议只使用Spotipy API。
问题出在我在Spotify后台创建的应用上……我也不太清楚为什么,但当我重新创建了这个应用,并使用了新的客户端ID、密钥和重定向地址后,我就能顺利登录了,脚本也正常运行。
可能是因为我之前运行了其他脚本尝试登录,导致浏览器出现了一些缓存问题吧?