我正在尝试使用 Spotipy 从我的所有歌曲 (5985) 中批量检索 100 首歌曲的audio_features。我使用的代码的简单版本没有异常处理,对于所有前 1416 个项目都工作得很好,然后它现在完全被阻止了。然后我尝试使用下面的代码来解决它:
def exponential_backoff_retry(func, *args, max_retries=3, base_delay=1, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except SpotifyException as e:
if e.http_status == 429:
print(f"Rate limited. Retrying in {base_delay * 2 ** attempt} seconds.")
time.sleep(base_delay * 2 ** attempt)
else:
raise e
print("Max retries exceeded. Unable to fetch track features.")
return None
def get_user_saved_track_features(sp, ids, start_track_id=None, batch_size=100):
tracks = []
# Iterate through each batch of track IDs
batches = [ids[i:i+batch_size] for i in range(start_track_id or 0, len(ids), batch_size)]
for batch in batches:
for track_id in batch:
meta = exponential_backoff_retry(sp.track, track_id)
name = meta['name']
album = meta['album']['name']
artist = meta['album']['artists'][0]['name']
release_date = meta['album']['release_date']
length = meta['duration_ms']
popularity = meta['popularity']
print(f"Processed meta for track ID {track_id}")
print(f"Processed all metatracks")
batch_features = exponential_backoff_retry(sp.audio_features, batch)
if batch_features:
for features in batch_features:
if features and features[0]:
print(f"Processing features {track_id}")
acousticness = features['acousticness']
danceability = features['danceability']
energy = features['energy']
instrumentalness = features['instrumentalness']
liveness = features['liveness']
loudness = features['loudness']
speechiness = features['speechiness']
tempo = features['tempo']
valence = features['valence']
time_signature = features['time_signature']
key = features['key']
mode = features['mode']
uri = features['uri']
tracks.append([name, album, artist, release_date, length, popularity,
acousticness, danceability, energy, instrumentalness,
liveness, loudness, speechiness, tempo, valence,
time_signature, key, mode, uri])
print(f"Processed track ID audio features {track_id}")
else:
print(f"Skipping track ID {track_id} because at least one feature value is None")
time.sleep(1) # Sleep for 1 second per song
elif batch_features is None:
print(f"Skipping batch due to error")
time.sleep(1) # Sleep for 1 second per batch to avoid rate limiting
# Create DataFrame from the list of track features
df = pd.DataFrame(tracks, columns=['name', 'album', 'artist', 'release_date',
'length', 'popularity', 'acousticness', 'danceability',
'energy', 'instrumentalness', 'liveness', 'loudness',
'speechiness', 'tempo', 'valence', 'time_signature',
'key', 'mode', 'uri'])
return df
奇怪的是,这部分的请求每次都被接受:
for track_id in batch:
meta = exponential_backoff_retry(sp.track, track_id)
name = meta['name']
album = meta['album']['name']
artist = meta['album']['artists'][0]['name']
release_date = meta['album']['release_date']
length = meta['duration_ms']
popularity = meta['popularity']
print(f"Processed meta for track ID {track_id}")
但是从
batch_features = exponential_backoff_retry(sp.audio_features, batch)
开始,“已达到最大重试次数”错误会从第一批甚至第一个功能中自动捕获。
我也尝试过更改
start_id
但没有成功。
根据您发布的错误消息,(代码为 429)错误响应是 HTTP 协议中的状态代码,指示 用户在给定时间内发送了太多请求(“速率限制”)。它通常由网络服务器用来防止滥用并确保资源的公平使用。
基本上,您可以:
了解这些限制可能会更好。
顺便说一句:速率限制很常见。