Spotipy无法向Spotify播放列表添加曲目问题求助
Apple Music播放列表转Spotify工具添加曲目功能故障排查
我正在开发一个通过网页抓取和Spotipy实现Apple Music播放列表转Spotify播放列表的工具,已将功能拆分为多个函数。其中爬取Apple网站数据、创建Spotify播放列表的功能正常,但添加曲目功能失效,Spotify账户中仅显示空播放列表。以下是负责搜索并添加曲目的get_spotify_tracks函数及完整代码,请求协助排查问题:
def get_spotify_tracks(songs, artists, sp, user_id): ''' Step 4: Transfer fetched song data Step 5: Search for song on Spotify Step 6: Add the songs to the Spotify playlist ''' list_of_tracks = [] prePlaylist = sp.user_playlists(user=user_id) playlist = prePlaylist["items"][0]["id"] for playlist_song, song_artist in zip(songs, artists): track_id = sp.search(q='artist:' + song_artist + ' track:' + playlist_song, type='track') #track_data = list(f'{playlist_song} by {song_artist}') #result = sp.search(q=track_data, ) #query = f"https://api.spotify.com/v1/serch?query=track%3A{playlist_song}" \ # f"+artist%3A{song_artist}&type=track&offset=0&limit=5" list_of_tracks.append(track_id["tracks"]["items"][0]["uri"]) print(list_of_tracks) query = f"https://api.spotify.com/v1/playlists/{playlist}/tracks" response = requests.post( query, data=list_of_tracks, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {token}" } ) return list_of_tracks
完整代码如下:
''' Making a program that converts an Apple music playlist to a Spotify Playlist Step1: Fetch the Apple music playlist data Step2: Get Authorization to spotify account Step3: Create new spotify playlist Step4: Transfer fetched song data Step5: Search for song on Spotify Step6: Add the songs to Spotify playlist ''' clientid = os.environ['CLIENT_ID'] client_secret = os.environ['CLIENT_SECRET'] token = os.environ['ACCESS_TOKEN'] username = os.environ['USERNAME'] track_list = [] artist_list = [] def get_apple_playlist(URL): ''' Step1: Fetch the Apple music playlist data ''' headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36", "Accept-Language": "en-US,en;q=0.9" } # pass in apple playlist link apple_link = requests.get(URL, headers=headers) # Use Beautiful soup to retrieve page html playlist_soup = BeautifulSoup(apple_link.content, "lxml") # Find various playlist info with Beautiful soup playlist_name = playlist_soup.find('h1', attrs={'data-testid': 'non-editable-product-title'}).get_text(strip=True) playlist_description = playlist_soup.find('p', attrs={'data-testid': 'truncate-text'}).get_text(strip=True) songs_raw = playlist_soup.find_all("div", class_="songs-list-row__song-name") artists_raw = playlist_soup.find_all("div", class_="songs-list__col songs-list__col--artist typography-body") #song_art = [playlist_soup.find_all("div picture source", type="image/jpeg").get_] #Refining data for song in songs_raw: track_list.append(song.get_text(strip=True)) for artist in artists_raw: artist_list.append(artist.get_text(strip=True)) return playlist_name, playlist_description, track_list, artist_list def spotify_playlist(playlist_name, playlist_description): ''' Step 2: Get Authorization to spotify account Step 3: Create new spotify playlist ''' token = SpotifyOAuth(client_id=clientid, client_secret=client_secret, redirect_uri="http://127.0.0.1:8080/", scope="playlist-modify-public") sp = spotipy.Spotify(auth_manager=token) user_id = sp.current_user()['id'] new_playlist = sp.user_playlists_create(user=user_id, name=playlist_name, description=playlist_description, public=True) playlist_id = new_playlist['id'] return playlist_id, user_id, sp def get_spotify_tracks(songs, artists, sp, user_id): ''' Step 4: Transfer fetched song data Step 5: Search for song on Spotify Step 6: Add the songs to the Spotify playlist ''' list_of_tracks = [] prePlaylist = sp.user_playlists(user=user_id) playlist = prePlaylist["items"][0]["id"] for playlist_song, song_artist in zip(songs, artists): track_id = sp.search(q='artist:' + song_artist + ' track:' + playlist_song, type='track') #track_data = list(f'{playlist_song} by {song_artist}') #result = sp.search(q=track_data, ) #query = f"https://api.spotify.com/v1/serch?query=track%3A{playlist_song}" \ # f"+artist%3A{song_artist}&type=track&offset=0&limit=5" list_of_tracks.append(track_id["tracks"]["items"][0]["uri"]) print(list_of_tracks) query = f"https://api.spotify.com/v1/playlists/{playlist}/tracks" response = requests.post( query, data=list_of_tracks, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {token}" } ) return list_of_tracks def main(url): ''' Execution ''' playlist_data = get_apple_playlist(url) playlist = spotify_playlist(playlist_data[0], playlist_data[1]) tracks = get_spotify_tracks(playlist_data[2], playlist_data[3], playlist[2], playlist[1]) main("https://music.apple.com/ng/playlist/angry/pl.u-PDbYmE4Ie084DqR")
核心问题分析
播放列表ID获取错误
你在get_spotify_tracks中通过prePlaylist["items"][0]["id"]获取的是用户的第一个播放列表,而非刚创建的目标播放列表。spotify_playlist函数已经返回了新创建的播放列表ID,直接传入即可,无需重新查询。手动API调用参数不规范
- Spotify API要求添加曲目时,请求体是
{"uris": ["uri1", "uri2"]}格式的JSON,你直接传列表list_of_tracks不符合要求。 - 全局环境变量的
token和SpotifyOAuth生成的令牌可能不一致,建议直接使用Spotipy内置的playlist_add_items方法,避免手动处理授权和请求格式。
- Spotify API要求添加曲目时,请求体是
未处理搜索无结果的异常
当sp.search未找到对应曲目时,track_id["tracks"]["items"][0]会触发索引越界错误,导致程序中断。
修复后的代码
修改get_spotify_tracks函数
def get_spotify_tracks(songs, artists, sp, playlist_id): ''' Step 4: Transfer fetched song data Step 5: Search for song on Spotify Step 6: Add the songs to the Spotify playlist ''' list_of_tracks = [] for playlist_song, song_artist in zip(songs, artists): # 优化查询语句,处理特殊字符 query = f'artist:"{song_artist}" track:"{playlist_song}"' track_results = sp.search(q=query, type='track', limit=1) # 检查是否搜索到结果 if track_results["tracks"]["items"]: track_uri = track_results["tracks"]["items"][0]["uri"] list_of_tracks.append(track_uri) print(f"找到曲目:{playlist_song} - {song_artist}") else: print(f"未找到曲目:{playlist_song} - {song_artist}") # 使用Spotipy内置方法添加曲目 if list_of_tracks: sp.playlist_add_items(playlist_id=playlist_id, items=list_of_tracks) print(f"成功添加{len(list_of_tracks)}首曲目到播放列表") return list_of_tracks
修改main函数
def main(url): ''' Execution ''' playlist_data = get_apple_playlist(url) # 解构返回值,直接获取新播放列表ID playlist_id, user_id, sp = spotify_playlist(playlist_data[0], playlist_data[1]) tracks = get_spotify_tracks(playlist_data[2], playlist_data[3], sp, playlist_id)
额外优化建议
- 将全局变量
track_list和artist_list改为get_apple_playlist函数内部变量,避免多次调用时数据累积。 - 在
get_apple_playlist中,若歌曲或艺术家列表为空,可添加判断逻辑提前返回提示。
内容的提问来源于stack exchange,提问作者Robinson T
相关产品推荐
相关产品推荐

