如何获取Spotify播放列表全部曲目?Offset参数分页失效问题排查
分页失效问题解析与修复方案
嘿,我帮你找到了导致分页一直返回前100首的核心原因,还有几个代码里的小bug,咱们一步步梳理:
核心问题:错误解析Spotipy响应结构
这是分页失效的根本原因:你混淆了sp.playlist()和sp.playlist_tracks()的返回结构!
sp.playlist_tracks()是专门用来获取播放列表曲目分页数据的接口,它返回的字典顶层直接包含total(总曲目数)和items(当前页曲目),根本没有嵌套的tracks键。- 但你的代码里错误地尝试从
tracks_data['tracks']['total']和tracks_data['tracks']['items']取值,这不仅会导致total无法被正确更新为实际总曲目数,还会让你每次都取不到正确的曲目数据(甚至可能抛出KeyError,除非你悄悄捕获了异常没写出来)。
其他需要修复的小问题
- 冗余的JSON序列化/反序列化:
sp.playlist_tracks()直接返回Python字典,完全没必要先用json.dumps转成字符串再用json.loads转回来,纯纯的多余操作。 - 未定义的
row_num变量:代码里直接用了row_num但没初始化,运行时肯定会抛出NameError。 - 文件管理不严谨:手动调用
data_file.close()容易遗漏,最好用with语句自动管理文件生命周期。
修复后的完整代码
import spotipy, csv from spotipy.oauth2 import SpotifyClientCredentials # 替换成你的实际客户端ID和密钥 client_id = "your_client_id_here" client_secret = "your_client_secret_here" client_credentials_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) # 使用with语句自动处理文件打开/关闭 with open('data.csv', 'w', newline='') as data_file: writer = csv.writer(data_file) writer.writerow(['track_num', 'track_id', 'track_name', 'first_artist', 'liked']) playlist_ids = [ 'xxxxxxxxxxxxxxxxxxxxxxx', # playlist 1 'yyyyyyyyyyyyyyyyyyyyyyy' # playlist 2 ] row_num = 1 # 初始化行号计数器 for playlist_id in playlist_ids: offset_n = 0 total_tracks = 0 while True: # 显式指定limit=100(默认值也是100,写出来更清晰) tracks_response = sp.playlist_tracks(playlist_id, offset=offset_n, limit=100) total_tracks = tracks_response['total'] current_page_tracks = tracks_response['items'] # 如果当前页没有曲目,提前退出循环 if not current_page_tracks: break for track_entry in current_page_tracks: # 处理特殊情况:部分曲目可能是本地文件,track字段为None if track_entry['track'] is None: continue track_id = track_entry['track']['id'] track_name = track_entry['track']['name'] first_artist = track_entry['track']['artists'][0]['name'] # 根据播放列表设置liked标记 liked_status = 1 if playlist_id == playlist_ids[0] else 0 writer.writerow([row_num, track_id, track_name, first_artist, liked_status]) row_num += 1 offset_n += 100 # 当偏移量超过总曲目数时,终止分页循环 if offset_n >= total_tracks: break
额外优化说明
- 增加了对
track_entry['track']为None的判断,避免遇到本地文件或无效曲目时崩溃。 - 用更清晰的变量名(比如
total_tracks、current_page_tracks)提升代码可读性。 - 显式判断
offset_n >= total_tracks来终止循环,逻辑更直观。
内容的提问来源于stack exchange,提问作者Ece Akdeniz




