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

使用Spotify API获取当前播放歌曲时偶现KeyError及401权限缺失问题求助

问题描述

我正尝试使用Spotify API检索并打印我的账户中当前播放的歌曲。在代码完全未作任何改动的情况下,该功能有时正常运行,有时却失败。我收到的错误信息如下:

Traceback (most recent call last):
File "main.py", line 64, in <module>
main()
File "main.py", line 22, in main
current_track_info = get_current_track(SPOTIFY_ACCESS_TOKEN)
File "main.py", line 50, in get_current_track
track_name = resp_json['item']['name']
KeyError: 'item'

这个错误应该意味着未找到"item"字段,对吗?但我当时正在Spotify账户中播放音乐,并且刚获取并输入了全新的access token。该功能仅约10%的概率能正常运行,且代码始终无任何改动。使用相同的授权token在Spotify的Web控制台中可以正常工作,但在我自己的程序中却不行。在尝试相关代码后打印的JSON响应结果为:

{'error': {'message': 'Permissions missing', 'status': 401}}

以下是我的代码:

import requests
from pprint import pprint

SPOTIFY_GET_CURRENT_TRACK_URL = 'https://api.spotify.com/v1/me/player/currently-playing'
ACCESS_TOKEN = ''

def get_current_track(access_token):
    response = requests.get(
        SPOTIFY_GET_CURRENT_TRACK_URL,
        headers={"Authorization": f"Bearer {access_token}"}
    )
    json_resp = response.json()

    track_id = json_resp['item']['id']
    track_name = json_resp['item']['name']
    artists = [artist for artist in json_resp['item']['artists']]
    link = json_resp['item']['external_urls']['spotify']

    artist_names = ', '.join([artist['name'] for artist in artists])

    current_track_info = {
        "id": track_id,
        "track_name": track_name,
        "artists": artist_names,
        "link": link
    }
    return current_track_info

def main():
    current_track_id = None
    while True:
        current_track_info = get_current_track(ACCESS_TOKEN)
        if current_track_info['id'] != current_track_id:
            pprint(
                current_track_info,
                indent=4,
            )
            current_track_id = current_track_info['id']

if __name__ == '__main__':
    main()

我是Python和API的新手,任何帮助都将不胜感激!


问题分析与解决方案

1. 核心问题拆解

你遇到的KeyError: 'item'其实是个连锁问题:首先API返回了权限缺失的错误响应(就是你看到的Permissions missing),但你的代码完全没做错误处理,直接默认响应里一定有item字段,自然就触发了KeyError。

至于为什么Web控制台能用但自己的代码不行?大概率是你在控制台测试时,授权流程已经包含了接口所需的权限,但自己获取token时漏加了必要的权限范围(scope)。

2. 分步解决

(1)补全获取token时的权限范围

Spotify的/me/player/currently-playing接口必须要求user-read-currently-playing这个权限scope,如果你需要读取更详细的播放状态,还可以加上user-read-playback-state。

在获取access token的授权请求里,要把这些scope加进去,比如授权URL里需要包含:

scope=user-read-currently-playing%20user-read-playback-state

注意多个scope之间用%20(URL编码的空格)分隔,重新获取包含这些权限的token再测试。

(2)给代码添加错误处理逻辑

你的代码现在直接硬取json_resp['item'],完全没考虑API返回错误或者没有播放内容的情况,咱们来修改get_current_track函数:

def get_current_track(access_token):
    response = requests.get(
        SPOTIFY_GET_CURRENT_TRACK_URL,
        headers={"Authorization": f"Bearer {access_token}"}
    )
    
    # 先检查响应状态码,非200直接处理错误
    if response.status_code != 200:
        print(f"API请求失败,状态码: {response.status_code}")
        json_resp = response.json()
        if 'error' in json_resp:
            print(f"错误详情: {json_resp['error']['message']}")
        return None  # 返回None表示获取失败
    
    json_resp = response.json()
    
    # 额外检查是否有item字段(比如暂停播放时也可能没有item)
    if 'item' not in json_resp:
        print("当前没有正在播放的歌曲")
        return None
    
    track_id = json_resp['item']['id']
    track_name = json_resp['item']['name']
    artists = [artist for artist in json_resp['item']['artists']]
    link = json_resp['item']['external_urls']['spotify']

    artist_names = ', '.join([artist['name'] for artist in artists])

    current_track_info = {
        "id": track_id,
        "track_name": track_name,
        "artists": artist_names,
        "link": link
    }
    return current_track_info

(3)主循环适配错误情况

修改main函数,避免因为返回None而报错,同时加个延迟防止频繁请求被限流:

def main():
    current_track_id = None
    while True:
        current_track_info = get_current_track(ACCESS_TOKEN)
        # 只有获取到有效信息且歌曲变化时才打印
        if current_track_info is not None and current_track_info['id'] != current_track_id:
            pprint(
                current_track_info,
                indent=4,
            )
            current_track_id = current_track_info['id']
        # 每5秒检查一次,避免请求过于频繁
        import time
        time.sleep(5)

3. 额外提示

如果之后还是偶尔出现问题,可以检查token是否过期——Spotify的access token默认有效期是1小时,需要用refresh token去刷新,不过如果是测试阶段,重新获取新的token也能临时解决。

内容的提问来源于stack exchange,提问作者Luke Sanford

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:50:52