You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Spotipy脚本解决爬取Spotify R&B歌曲的超时错误

解决Spotipy爬取时的Maximum Retries/ReadTimeout错误方案

问题本质

这类错误要么是请求频率撞了Spotify API的速率限制(普通用户每分钟最多180次请求,单日上限15000次),要么是网络不稳定导致请求超时,核心是要控制请求节奏、优化调用方式。

具体修改方案

1. 加请求延迟+指数退避重试

给API调用套一层重试逻辑,正常请求后加随机延迟,遇到错误时逐步拉长重试间隔,避免硬怼限流:

import time
import random
from spotipy.exceptions import SpotifyException
import requests

def safe_api_call(func, *args, **kwargs):
    max_retries = 5
    retry_delay = 1  # 初始延迟1秒
    for attempt in range(max_retries):
        try:
            result = func(*args, **kwargs)
            # 正常请求后加0.5-2秒的随机延迟
            time.sleep(random.uniform(0.5, 2))
            return result
        except (SpotifyException, requests.exceptions.ReadTimeout) as e:
            if attempt == max_retries - 1:
                raise e
            # 指数退避:每次延迟翻倍,再加随机抖动避免固定间隔
            time.sleep(retry_delay + random.uniform(0, 1))
            retry_delay *= 2

使用时把原来的sp.track(track_id)换成safe_api_call(sp.track, track_id),sp.audio_features()同理。

2. 初始化Spotipy时配置超时与重试

显式设置超时时间,同时开启内置重试,减少因网络波动触发的超时:

import spotipy
from spotipy.oauth2 import SpotifyClientCredentials

sp = spotipy.Spotify(
    auth_manager=SpotifyClientCredentials(client_id="你的ID", client_secret="你的密钥"),
    requests_timeout=10,  # 设置10秒超时,根据网络情况调整
    retries=3  # 内置重试次数
)

3. 用批量请求减少API调用次数

Spotify很多接口支持批量查询,比如audio_features一次可以传最多100个track_id,别一个个单独请求:

# 错误示例:单条请求
for track_id in track_ids:
    features = sp.audio_features(track_id)

# 正确示例:批量请求
for i in range(0, len(track_ids), 100):
    batch_ids = track_ids[i:i+100]
    features_batch = safe_api_call(sp.audio_features, batch_ids)
    # 批量处理返回的特征数据

4. 分页爬取时遵循规范

爬取搜索结果、播放列表这类分页数据,必须用Spotipy的next()方法,不要自己拼URL,同时分页后加延迟:

# 搜索2018-2023年的R&B歌曲
results = safe_api_call(sp.search, q="genre:r&b year:2018-2023", type="track", limit=50)
while results:
    # 处理当前页的歌曲数据
    for item in results['tracks']['items']:
        track_id = item['id']
        # 提取歌曲信息、合作者等
    # 分页请求下一页
    results = safe_api_call(sp.next, results['tracks']) if results['tracks']['next'] else None

合作者信息提取技巧

不用额外调用API,直接从track对象的artists字段提取就行,省请求:

track = safe_api_call(sp.track, track_id)
# 排除主艺人,剩下的就是合作者
collaborators = [artist['name'] for artist in track['artists'] if artist['id'] != track['artists'][0]['id']]

内容的提问来源于stack exchange,提问作者Ava Serin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:10:54