Spotipy应用无法识别重复曲目,执行后未删除歌曲求助
问题:Spotipy脚本无法识别并删除歌单重复曲目
我开发了一个基于Spotipy的Python脚本,用于移除Spotify歌单中的重复曲目。脚本启动后无报错,正常跳转至授权页面,完成授权后脚本执行结束,但未删除任何歌曲。脚本运行时会打印重复曲目,但输出的字典为空,推测应用无法识别重复曲目,期望实现删除重复歌曲的功能。
原脚本代码:
import spotipy from spotipy.oauth2 import SpotifyOAuth import re def get_playlist_id(url): playlist_id = re.search(r'/playlist/([a-zA-Z0-9]+)', url) if playlist_id: return playlist_id.group(1) else: return None def get_duplicates(tracks): duplicates = {} for track in tracks: key = f"{track['track']['name']} - {track['track']['artists'][0]['name']}" if key in duplicates: duplicates[key].append(track['track']['id']) else: duplicates[key] = [track['track']['id']] duplicate_tracks = {key: ids for key, ids in duplicates.items() if len(ids) > 1} print("Duplicate tracks:", duplicate_tracks) return duplicate_tracks def remove_duplicates(sp, playlist_id): playlist_tracks = sp.playlist_tracks(playlist_id)['items'] duplicates = get_duplicates(playlist_tracks) for ids in duplicates.values(): for track_id in ids[1:]: sp.playlist_remove_all_occurrences_of_items(playlist_id, [track_id]) def main(): scope = "playlist-read-collaborative playlist-modify-public" client_id = 'my client ID' client_secret = 'my client secret' redirect_uri = 'http://localhost:3036' sp = spotipy.Spotify( auth_manager=SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=scope)) playlist_url = 'https://open.spotify.com/playlist/1x76RxwKGwGq5oP3xofc3o?si=710c91480cb64fb6' playlist_id = get_playlist_id(playlist_url) if playlist_id: remove_duplicates(sp, playlist_id) else: print("Fehler: Playlist-ID konnte nicht aus der URL extrahiert werden.") if __name__ == "__main__": main()
问题排查与修复方案
1. 修复曲目分页获取问题
Spotify API的playlist_tracks接口默认只返回100条曲目,需循环获取所有分页数据:
def get_all_playlist_tracks(sp, playlist_id): tracks = [] results = sp.playlist_tracks(playlist_id) tracks.extend(results['items']) while results['next']: results = sp.next(results) tracks.extend(results['items']) return tracks
2. 优化重复项判断逻辑
- 跳过
track为None的无效条目 - 改用唯一的
track_id作为核心判断依据(更准确,避免同名不同曲的误判),同时保留曲目名+艺术家的标识用于输出:
def get_duplicates(tracks): track_map = {} duplicates = {} for item in tracks: track = item['track'] if not track: continue # 跳过无效曲目 track_id = track['id'] track_key = f"{track['name']} - {track['artists'][0]['name']}" if track_id in track_map: # 记录重复项 if track_key not in duplicates: duplicates[track_key] = [track_map[track_id]] duplicates[track_key].append(item['id']) # 用歌单条目的id,而非track_id,删除更准确 else: track_map[track_id] = item['id'] print("Duplicate tracks:", duplicates) return duplicates
3. 补充权限范围
如果操作私有歌单,需添加playlist-modify-private权限:
scope = "playlist-read-collaborative playlist-modify-public playlist-modify-private"
4. 优化删除逻辑
使用歌单条目的item['id']而非track['id']调用playlist_remove_items,删除更精准:
def remove_duplicates(sp, playlist_id): playlist_tracks = get_all_playlist_tracks(sp, playlist_id) duplicates = get_duplicates(playlist_tracks) for item_ids in duplicates.values(): # 保留第一个条目,删除后续重复条目 sp.playlist_remove_items(playlist_id, item_ids[1:])
修复后的完整代码
import spotipy from spotipy.oauth2 import SpotifyOAuth import re def get_playlist_id(url): playlist_id = re.search(r'/playlist/([a-zA-Z0-9]+)', url) if playlist_id: return playlist_id.group(1) else: return None def get_all_playlist_tracks(sp, playlist_id): tracks = [] results = sp.playlist_tracks(playlist_id) tracks.extend(results['items']) while results['next']: results = sp.next(results) tracks.extend(results['items']) return tracks def get_duplicates(tracks): track_map = {} duplicates = {} for item in tracks: track = item['track'] if not track: continue track_id = track['id'] track_key = f"{track['name']} - {track['artists'][0]['name']}" if track_id in track_map: if track_key not in duplicates: duplicates[track_key] = [track_map[track_id]] duplicates[track_key].append(item['id']) else: track_map[track_id] = item['id'] print("Duplicate tracks:", duplicates) return duplicates def remove_duplicates(sp, playlist_id): playlist_tracks = get_all_playlist_tracks(sp, playlist_id) duplicates = get_duplicates(playlist_tracks) for item_ids in duplicates.values(): sp.playlist_remove_items(playlist_id, item_ids[1:]) def main(): scope = "playlist-read-collaborative playlist-modify-public playlist-modify-private" client_id = 'my client ID' client_secret = 'my client secret' redirect_uri = 'http://localhost:3036' sp = spotipy.Spotify( auth_manager=SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=scope)) playlist_url = 'https://open.spotify.com/playlist/1x76RxwKGwGq5oP3xofc3o?si=710c91480cb64fb6' playlist_id = get_playlist_id(playlist_url) if playlist_id: remove_duplicates(sp, playlist_id) else: print("Fehler: Playlist-ID konnte nicht aus der URL extrahiert werden.") if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者ZickZackCCC
相关产品推荐
相关产品推荐

