如何用Spotipy根据歌曲名与影片年份查询Spotify歌曲URI?
使用Spotipy获取影片关联歌曲的Spotify URI问题解决
问题背景
现有数据集包含歌曲名、影片名、影片年份字段,需通过Python调用Spotipy库批量获取对应歌曲的Spotify URI。最初尝试按「歌曲名+影片年份」搜索时报错,后续计划改为「歌曲名+影片名」搜索(因Spotify平台的影视原声合辑通常包含影片名)。
错误代码示例
import spotipy from spotipy.oauth2 import SpotifyClientCredentials import json # 未导入pandas库会导致pd.read_csv报错 credentials = json.load(open('autorizzazione.json')) client_id = credentials['client_id'] client_secret = credentials['client_secret'] client_credentials_manager = SpotifyClientCredentials(client_id=client_id,client_secret=client_secret) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) listasong = pd.read_csv("dataset.csv") # 此处参数使用错误导致报错 research = sp.search([listasong["track"][0],listasong["year"][0]] , limit=1, offset=0, type=["track, year"] , market=None) ##track是存储歌曲名的列名
报错原因
- 搜索词参数错误:
sp.search要求搜索词为字符串,不能传入列表; - 类型参数非法:
type仅支持Spotify官方定义的资源类型(如"track"),不能包含"year"这类非资源类型; - 缺失依赖库:代码中使用
pd.read_csv但未导入pandas库,会引发NameError。
修正后的实现方案
1. 基础准备
先导入所有依赖库并完成Spotify授权:
import spotipy import pandas as pd import json from spotipy.oauth2 import SpotifyClientCredentials # 加载授权信息 credentials = json.load(open('autorizzazione.json')) client_id = credentials['client_id'] client_secret = credentials['client_secret'] # 初始化Spotify客户端 client_credentials_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) # 读取数据集 df = pd.read_csv("dataset.csv")
2. 方式1:按「歌曲名+影片年份」搜索
利用Spotify搜索语法,通过year:前缀指定年份过滤,提升匹配准确性:
def get_uri_by_track_year(track_name, year): # 构造搜索字符串:歌曲名 + 年份过滤 query = f"{track_name} year:{year}" try: result = sp.search(q=query, limit=1, type="track", market=None) # 提取第一个匹配结果的URI return result['tracks']['items'][0]['uri'] if result['tracks']['items'] else None except Exception as e: print(f"搜索出错:{e}") return None # 批量处理数据集 df['spotify_uri_year'] = df.apply(lambda row: get_uri_by_track_year(row['track'], row['year']), axis=1)
3. 方式2:按「歌曲名+影片名」搜索
针对影视原声合辑的特点,优先按「歌曲名+专辑包含影片名」搜索,无结果则降级为直接搜索歌曲+影片名:
def get_uri_by_track_movie(track_name, movie_name): # 优先按专辑包含影片名搜索 query = f"{track_name} album:{movie_name}" try: result = sp.search(q=query, limit=1, type="track", market=None) if result['tracks']['items']: return result['tracks']['items'][0]['uri'] # 无结果则尝试直接搜索歌曲+影片名 query_backup = f"{track_name} {movie_name}" result_backup = sp.search(q=query_backup, limit=1, type="track", market=None) return result_backup['tracks']['items'][0]['uri'] if result_backup['tracks']['items'] else None except Exception as e: print(f"搜索出错:{e}") return None # 批量处理数据集 df['spotify_uri_movie'] = df.apply(lambda row: get_uri_by_track_movie(row['track'], row['movie']), axis=1) # 保存结果到新CSV df.to_csv("dataset_with_spotify_uri.csv", index=False)
内容的提问来源于stack exchange,提问作者Lukesky
相关产品推荐
相关产品推荐

