Spotipy授权方式错误及播放列表分析403报错的解决求助
Spotipy授权方式错误及播放列表分析403报错的解决求助
我最近在练习用Spotify API提取音频特征,参考了一份Spotipy入门的notebook,但过程中遇到了两个问题,希望有经验的朋友能帮忙解答!
一、初始授权代码的AttributeError问题
最开始我用这段代码获取授权:
token = util.oauth2.SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET) cache_token = token.get_access_token() sp = spotipy.Spotify(cache_token)
结果直接触发了AttributeError:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[4], line 1 ----> 1 token = util.oauth2.SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET) 2 cache_token = token.get_access_token() 3 sp = spotipy.Spotify(cache_token) AttributeError: module 'spotipy.util' has no attribute 'oauth2'
二、修改授权方式后出现403 Forbidden报错
后来我查了资料,把授权代码改成了Spotipy官方推荐的方式,授权这部分暂时没问题了,但当我调用自定义的analyze_playlist函数时:
playlist_df = analyze_playlist(playlist_creator, playlist_id)
又触发了403 Forbidden的HTTP错误,完整报错信息如下:
HTTPError Traceback (most recent call last) File ~\anaconda3\lib\site-packages\spotipy\client.py:275, in Spotify._internal_call(self, method, url, payload, params) 270 response = self._session.request( 271 method, url, headers=headers, proxies=self.proxies, 272 timeout=self.requests_timeout, **args 273 ) --> 275 response.raise_for_status() 276 results = response.json() File ~\anaconda3\lib\site-packages\requests\models.py:1021, in Response.raise_for_status(self) 1020 if http_error_msg: -> 1021 raise HTTPError(http_error_msg, response=self) HTTPError: 403 Client Error: Forbidden for url: https://api.spotify.com/v1/audio-features/?ids=3AWDeHLc88XogCaCnZQLVI During handling of the above exception, another exception occurred: SpotifyException Traceback (most recent call last) Cell In[60], line 1 --> 1 playlist_df = analyze_playlist(playlist_creator, playlist_id) Cell In[59], line 21, in analyze_playlist(creator, playlist_id) 19 playlist_features["track_id"] = track["track"]["id"] 20 # Get audio features --> 21 audio_features = sp.audio_features(playlist_features["track_id"])[0] 22 for feature in playlist_features_list[4:]: 23 playlist_features[feature] = audio_features[feature] File ~\anaconda3\lib\site-packages\spotipy\client.py:1799, in Spotify.audio_features(self, tracks) 1797 if isinstance(tracks, str): 1798 trackid = self._get_id("track", tracks) -> 1799 results = self._get("audio-features/?ids=" + trackid) 1800 else: 1801 tlist = [self._get_id("track", t) for t in tracks] File ~\anaconda3\lib\site-packages\spotipy\client.py:327, in Spotify._get(self, url, args, payload, **kwargs) 324 if args: 325 kwargs.update(args) --> 327 return self._internal_call("GET", url, payload, kwargs) File ~\anaconda3\lib\site-packages\spotipy\client.py:297, in Spotify._internal_call(self, method, url, payload, params) 290 reason = None 292 logger.error( 293 'HTTP Error for %s to %s with Params: %s returned %s due to %s', 294 method, url, args.get("params"), response.status_code, msg 295 ) --> 297 raise SpotifyException( 298 response.status_code, 299 -1, 300 f"{response.url}:\n {msg}", 301 reason=reason, 302 headers=response.headers, 303 ) 304 except requests.exceptions.RetryError as retry_error: 305 request = retry_error.request SpotifyException: http status: 403, code:-1 - https://api.spotify.com/v1/audio-features/?ids=3AWDeHLc88XogCaCnZQLVI: None, reason: None
我的完整代码
下面是我目前写的全部代码,麻烦大家帮我看看哪里出了问题:
import spotipy from spotipy.oauth2 import SpotifyClientCredentials import pandas as pd CLIENT_ID = "myidfromapidashboard" CLIENT_SECRET = "mysecretfromapidashboard" # 注意:这段是我最初用的旧授权代码,实际运行时已经注释/替换为下面的新授权方式 # token = util.oauth2.SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET) # cache_token = token.get_access_token() # sp = spotipy.Spotify(cache_token) # 新的授权代码 client_credentials_manager = SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) playlist_creator = "spotify" playlist_id = "37i9dQZF1DX5IDTimEWoTd" def analyze_playlist(creator, playlist_id): # Create empty dataframe playlist_features_list = ["artist", "album", "track_name", "track_id", "danceability", "energy", "key", "loudness", "mode", "speechiness", "instrumentalness", "liveness", "valence", "tempo", "duration_ms", "time_signature"] playlist_df = pd.DataFrame(columns = playlist_features_list) # Create empty dict playlist_features = {} # Loop through every track in the playlist, extract features and append the features to the playlist df playlist = sp.user_playlist_tracks(creator, playlist_id)["items"] for track in playlist: # Get metadata playlist_features["artist"] = track["track"]["album"]["artists"][0]["name"] playlist_features["album"] = track["track"]["album"]["name"] playlist_features["track_name"] = track["track"]["name"] playlist_features["track_id"] = track["track"]["id"] # Get audio features audio_features = sp.audio_features(playlist_features["track_id"])[0] for feature in playlist_features_list[4:]: playlist_features[feature] = audio_features[feature] # Concat the dfs track_df = pd.DataFrame(playlist_features, index = [0]) playlist_df = pd.concat([playlist_df, track_df], ignore_index = True) return playlist_df playlist_df = analyze_playlist(playlist_creator, playlist_id)
我已经卡在这好一会儿了,有没有朋友能帮我排查下问题所在?非常感谢!
备注:内容来源于stack exchange,提问作者ariel23
相关产品推荐
相关产品推荐

