Python调用Spotify API分析个人音乐DNA

📅 发布时间:2026/9/13 9:30:08
Python调用Spotify API分析个人音乐DNA
1. 项目概述用Python解锁你的音乐DNA作为一名长期使用Spotify的音乐爱好者兼Python开发者我发现平台提供的年度回顾Wrapped功能虽然有趣但远远不能满足深度分析需求。通过Python直接调用Spotify API我们可以挖掘出更多隐藏的听歌行为模式——比如你在工作日和周末的听歌风格差异、随着季节变化的音乐偏好迁移甚至是特定情绪状态下的选曲规律。这个项目特别适合想用技术手段量化个人音乐品味的数据爱好者需要音乐数据分析练手的Python初学者计划创建个性化音乐推荐系统的开发者单纯好奇自己听歌习惯的普通用户提示Spotify官方API对非商业用途非常友好免费账户也能获取足够丰富的听歌历史数据2. 环境准备与API配置2.1 创建Spotify开发者应用首先访问 Spotify开发者仪表板 用你的Spotify账号登录后点击Create App按钮填写应用名称如My Listening Analysis在应用描述中注明Personal use for music data analysis同意条款后点击Create创建成功后记录两个关键信息Client ID相当于你的应用身份证Client Secret用于验证的密钥2.2 安装必要的Python库推荐使用conda创建独立环境conda create -n spotify-analysis python3.9 conda activate spotify-analysis pip install spotipy pandas matplotlib seaborn其中各库的作用spotipy官方推荐的Spotify API Python客户端pandas数据处理与分析核心工具matplotlib/seaborn可视化黄金组合2.3 配置认证流程在项目目录创建config.json文件{ SPOTIPY_CLIENT_ID: 你的Client ID, SPOTIPY_CLIENT_SECRET: 你的Client Secret, SPOTIPY_REDIRECT_URI: http://localhost:8888/callback }重要安全提示永远不要将config.json上传到公开Git仓库建议添加到.gitignore3. 数据获取与清洗3.1 实现OAuth认证流程创建auth.py处理认证import spotipy from spotipy.oauth2 import SpotifyOAuth import json def get_spotify_client(): with open(config.json) as f: config json.load(f) scope user-library-read user-top-read user-read-recently-played return spotipy.Spotify(auth_managerSpotifyOAuth( scopescope, client_idconfig[SPOTIPY_CLIENT_ID], client_secretconfig[SPOTIPY_CLIENT_SECRET], redirect_uriconfig[SPOTIPY_REDIRECT_URI] ))这个scope参数表示我们需要三种权限读取收藏歌曲读取个人排行榜读取近期播放历史首次运行时会自动打开浏览器完成授权。3.2 获取核心听歌数据创建data_fetcher.pydef get_recent_tracks(sp, limit50): 获取最近播放的歌曲 results sp.current_user_recently_played(limitlimit) return [{ played_at: item[played_at], name: item[track][name], artist: , .join([a[name] for a in item[track][artists]]), duration_ms: item[track][duration_ms], id: item[track][id] } for item in results[items]] def get_top_items(sp, typetracks, time_rangemedium_term, limit50): 获取排行榜数据 return sp.current_user_top_items( typetype, time_rangetime_range, limitlimit )3.3 获取音频特征数据Spotify为每首歌提供了丰富的音频特征def get_audio_features(sp, track_ids): 批量获取音频特征 features [] for i in range(0, len(track_ids), 50): batch track_ids[i:i50] features sp.audio_features(batch) return features关键音频特征说明danceability节奏感 (0-1)energy能量感 (0-1)valence情绪积极度 (0-1)tempoBPM速度loudness响度 (dB)acousticness原声程度 (0-1)4. 数据分析与可视化4.1 听歌时间模式分析创建时间分布分析函数import pandas as pd from matplotlib import pyplot as plt def analyze_listening_times(df): # 转换时间戳 df[played_at] pd.to_datetime(df[played_at]) df[hour] df[played_at].dt.hour df[day_of_week] df[played_at].dt.dayofweek # 绘制小时分布 plt.figure(figsize(10,5)) df[hour].value_counts().sort_index().plot( kindbar, color#1DB954 ) plt.title(听歌时间分布小时) plt.xlabel(小时) plt.ylabel(播放次数) plt.savefig(listening_hours.png)4.2 音乐偏好雷达图创建音频特征可视化import numpy as np def plot_audio_profile(features_df): categories [danceability, energy, speechiness, acousticness, instrumentalness, valence] stats features_df[categories].mean().tolist() stats stats[:1] # 闭合雷达图 angles np.linspace(0, 2*np.pi, len(categories), endpointFalse).tolist() angles angles[:1] fig, ax plt.subplots(figsize(6,6), subplot_kw{polar: True}) ax.fill(angles, stats, color#1DB954, alpha0.25) ax.plot(angles, stats, color#1DB954, linewidth2) ax.set_xticks(angles[:-1]) ax.set_xticklabels(categories) ax.set_title(你的音乐DNA, pad20) plt.savefig(audio_profile.png)4.3 艺术家网络关系图分析艺术家合作模式import networkx as nx def build_artist_network(df): G nx.Graph() # 添加节点艺术家 all_artists set() for artists in df[artist].str.split(, ): all_artists.update(artists) for artist in all_artists: G.add_node(artist) # 添加边合作 for _, row in df.iterrows(): artists row[artist].split(, ) if len(artists) 1: for i in range(len(artists)): for j in range(i1, len(artists)): if G.has_edge(artists[i], artists[j]): G[artists[i]][artists[j]][weight] 1 else: G.add_edge(artists[i], artists[j], weight1) # 绘制网络 plt.figure(figsize(12,12)) pos nx.spring_layout(G) nx.draw_networkx_nodes(G, pos, node_size50) nx.draw_networkx_edges(G, pos, alpha0.2) nx.draw_networkx_labels(G, pos, font_size8) plt.title(艺术家关系网络) plt.savefig(artist_network.png)5. 高级分析与应用5.1 听歌情绪时间线结合音频特征创建情绪分析def plot_mood_timeline(df, features_df): # 合并时间与特征数据 mood_df pd.concat([ df[[played_at]], features_df[[valence, energy]] ], axis1) # 计算7天移动平均 mood_df[valence_smooth] mood_df[valence].rolling(7).mean() mood_df[energy_smooth] mood_df[energy].rolling(7).mean() # 绘制双轴图 fig, ax1 plt.subplots(figsize(12,6)) ax2 ax1.twinx() ax1.plot(mood_df[played_at], mood_df[valence_smooth], color#1DB954, label情绪) ax2.plot(mood_df[played_at], mood_df[energy_smooth], color#191414, label能量) ax1.set_ylabel(情绪值, color#1DB954) ax2.set_ylabel(能量值, color#191414) plt.title(听歌情绪时间线) plt.legend() plt.savefig(mood_timeline.png)5.2 创建个性化推荐系统基于听歌历史生成推荐def get_recommendations(sp, seed_tracks, limit10): return sp.recommendations( seed_tracksseed_tracks, limitlimit, target_danceability0.7, target_energy0.6 )5.3 导出分析报告使用Jinja2生成HTML报告from jinja2 import Environment, FileSystemLoader def generate_report(analysis_results): env Environment(loaderFileSystemLoader(.)) template env.get_template(report_template.html) html template.render( top_artistsanalysis_results[top_artists], top_tracksanalysis_results[top_tracks], audio_featuresanalysis_results[audio_features] ) with open(music_report.html, w) as f: f.write(html)6. 常见问题与优化建议6.1 API调用限制处理Spotify API有速率限制每分钟约300次请求建议import time def safe_api_call(func, *args, **kwargs): try: return func(*args, **kwargs) except spotipy.exceptions.SpotifyException as e: if e.http_status 429: retry_after int(e.headers.get(Retry-After, 5)) print(f达到限制等待{retry_after}秒) time.sleep(retry_after) return safe_api_call(func, *args, **kwargs) raise6.2 数据存储策略建议使用SQLite持久化数据import sqlite3 def init_db(): conn sqlite3.connect(spotify_data.db) c conn.cursor() c.execute(CREATE TABLE IF NOT EXISTS listening_history (id TEXT PRIMARY KEY, played_at TEXT, name TEXT, artist TEXT, duration_ms INTEGER)) conn.commit() return conn6.3 提升分析深度的技巧结合外部数据用last.fm API补充标签数据接入天气API分析天气对听歌影响高级分析方法from sklearn.cluster import KMeans def cluster_songs(features_df): # 选择特征列 X features_df[[danceability, energy, valence]] # 标准化 X (X - X.mean()) / X.std() # K-means聚类 kmeans KMeans(n_clusters3) features_df[cluster] kmeans.fit_predict(X) return features_df自动化部署方案使用Apache Airflow设置每日自动分析通过FastAPI创建个人分析仪表盘7. 完整项目架构建议spotify-analysis/ ├── config.json ├── auth.py ├── data/ │ ├── raw/ │ └── processed/ ├── analysis/ │ ├── time_analysis.py │ ├── audio_analysis.py │ └── network_analysis.py ├── utils/ │ ├── storage.py │ └── visualization.py ├── main.py └── requirements.txt实现main.py作为入口点from auth import get_spotify_client from data_fetcher import get_recent_tracks, get_audio_features from analysis.time_analysis import analyze_listening_times def main(): sp get_spotify_client() # 获取数据 recent_tracks get_recent_tracks(sp) track_ids [t[id] for t in recent_tracks] features get_audio_features(sp, track_ids) # 分析数据 analyze_listening_times(pd.DataFrame(recent_tracks)) if __name__ __main__: main()这个项目最有趣的部分在于随着你持续运行分析脚本会逐渐发现一些自己都没意识到的听歌模式。比如我自己就发现每逢阴雨天总会不自觉地播放更多独立民谣而周五下午的能量饮料时间则固定会出现电子音乐——这些隐藏在数据中的行为模式才是音乐分析最迷人的地方。