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
相关产品推荐
相关产品推荐

