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

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")

核心问题分析

  1. 播放列表ID获取错误
    你在get_spotify_tracks中通过prePlaylist["items"][0]["id"]获取的是用户的第一个播放列表,而非刚创建的目标播放列表。spotify_playlist函数已经返回了新创建的播放列表ID,直接传入即可,无需重新查询。

  2. 手动API调用参数不规范

    • Spotify API要求添加曲目时,请求体是{"uris": ["uri1", "uri2"]}格式的JSON,你直接传列表list_of_tracks不符合要求。
    • 全局环境变量的token和SpotifyOAuth生成的令牌可能不一致,建议直接使用Spotipy内置的playlist_add_items方法,避免手动处理授权和请求格式。
  3. 未处理搜索无结果的异常
    当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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:45:32