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

Python新手:Youtube转Spotify播放列表脚本故障排查求助

排查Spotify授权失败及脚本执行异常问题

首先来说你遇到的授权环节问题:

  • 当你粘贴回调URL后页面无法访问、脚本卡住,大概率是本地8888端口被占用,或者Spotify开发者后台的回调URL配置和你代码里的redirect_uri不完全一致(包括末尾的斜杠、http/https都要完全匹配)。spotipy的prompt_for_user_token会自动启动一个本地简易服务监听指定端口,如果端口被其他程序占了,就会导致授权回调无法跳转,脚本一直等待输入。

接下来是你的脚本本身存在的几个核心逻辑错误,这些问题即使授权成功了,脚本也无法正常工作:

1. Spotify客户端重复初始化+授权值错误

你在create_playlist、add_song_to_playlist里都调用了init_spotify_client(),这会导致每次操作都重新触发授权流程,更严重的是:init_spotify_client()返回的是Spotify客户端对象,而不是token字符串!你在请求头的Authorization: Bearer {}里放的是对象,这会导致API请求直接失败。

正确的做法是初始化一次客户端(或token),然后复用它,而不是每次都重新初始化。

2. info方法没有返回关键数据

你的info方法提取了song_name和artist,但没有用return返回这两个值,后续调用add_song_to_playlist时会拿不到歌曲和歌手信息,直接报错。

3. 主函数没有触发核心业务逻辑

你的main()函数只初始化了Spotify客户端和CreatePlaylist对象,但没有调用提取视频信息、创建播放列表、添加歌曲的方法,所以脚本执行到这里就结束了,没有完成任何实际操作。

4. Youtube-DL的兼容性问题

现在youtube-dl已经停止维护了,很多YouTube视频的元数据(比如track、artist)已经无法正确提取,建议换成yt-dlp(它是youtube-dl的活跃分支)。

修复后的完整代码

import json
import requests
from yt_dlp import YoutubeDL  # 替换成yt-dlp
import spotipy.util as util
import spotipy

username = '***' # 你的Spotify用户名
client_id = '***' # 你的客户端ID
client_secret = '***' # 你的客户端密钥
redirect_uri = 'http://localhost:8888/callback/'
scope = 'playlist-modify-private'

def init_spotify_client():
    print('Initialising Spotify Client....')
    token = util.prompt_for_user_token(username, scope, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri)
    # 返回token和客户端对象,方便后续复用
    return token, spotipy.Spotify(auth=token)

class CreatePlaylist:
    def __init__(self, youtube_url, spotify_token, spotify_client):
        self.youtube_url = youtube_url
        self.spotify_token = spotify_token
        self.spotify_client = spotify_client

    def get_song_info(self):
        # 提取YouTube视频的歌曲名和歌手
        ydl_opts = {'quiet': True}
        with YoutubeDL(ydl_opts) as ydl:
            video_info = ydl.extract_info(self.youtube_url, download=False)
            # 兼容不同视频的元数据格式,避免提取失败
            song_name = video_info.get('track') or video_info.get('title')
            artist = video_info.get('artist') or video_info.get('uploader')
            return song_name, artist

    def create_playlist(self):
        """创建私有播放列表"""
        # 直接用spotipy客户端调用API,比手动requests更简洁
        playlist = self.spotify_client.user_playlist_create(
            user=username,
            name="Youtube Liked Vids",
            description="All Liked Youtube Videos",
            public=False
        )
        print(f"Created playlist with ID: {playlist['id']}")
        return playlist['id']

    def add_song_to_playlist(self):
        song_name, artist = self.get_song_info()
        if not song_name or not artist:
            print("无法提取歌曲或歌手信息")
            return

        # 搜索Spotify上的歌曲
        results = self.spotify_client.search(q=f"track:{song_name} artist:{artist}", type='track', limit=1)
        if not results['tracks']['items']:
            print(f"未找到歌曲:{song_name} - {artist}")
            return

        song_uri = results['tracks']['items'][0]['uri']
        playlist_id = self.create_playlist()

        # 添加歌曲到播放列表
        self.spotify_client.playlist_add_items(playlist_id=playlist_id, items=[song_uri])
        print(f"已添加歌曲 {song_name} - {artist} 到播放列表")

def main():
    # 初始化一次Spotify客户端和token
    spotify_token, spotify_client = init_spotify_client()
    print('\nClient initialised!\n')

    youtube_url = "https://www.youtube.com/watch?v=Bx5QlA8xp28"
    cp = CreatePlaylist(youtube_url, spotify_token, spotify_client)
    # 触发添加歌曲的核心逻辑
    cp.add_song_to_playlist()

if __name__ == "__main__":
    main()

额外注意事项

  • 先安装依赖:pip install spotipy yt-dlp requests
  • 确保Spotify开发者后台的回调URL和代码里的redirect_uri完全一致(包括末尾的斜杠)
  • 如果还是遇到端口占用问题,可以把redirect_uri改成其他端口,比如http://localhost:9999/callback/,同时更新开发者后台的配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:37:33