Python调用Spotify API分析个人音乐DNA
2026/9/13 9:30:04 网站建设 项目流程

1. 项目概述:用Python解锁你的音乐DNA

作为一名长期使用Spotify的音乐爱好者兼Python开发者,我发现平台提供的年度回顾(Wrapped)功能虽然有趣,但远远不能满足深度分析需求。通过Python直接调用Spotify API,我们可以挖掘出更多隐藏的听歌行为模式——比如你在工作日和周末的听歌风格差异、随着季节变化的音乐偏好迁移,甚至是特定情绪状态下的选曲规律。

这个项目特别适合:

  • 想用技术手段量化个人音乐品味的数据爱好者
  • 需要音乐数据分析练手的Python初学者
  • 计划创建个性化音乐推荐系统的开发者
  • 单纯好奇自己听歌习惯的普通用户

提示:Spotify官方API对非商业用途非常友好,免费账户也能获取足够丰富的听歌历史数据

2. 环境准备与API配置

2.1 创建Spotify开发者应用

首先访问 Spotify开发者仪表板 ,用你的Spotify账号登录后:

  1. 点击"Create App"按钮
  2. 填写应用名称(如"My Listening Analysis")
  3. 在应用描述中注明"Personal use for music data analysis"
  4. 同意条款后点击"Create"

创建成功后记录两个关键信息:

  • Client ID:相当于你的应用身份证
  • Client Secret:用于验证的密钥

2.2 安装必要的Python库

推荐使用conda创建独立环境:

conda create -n spotify-analysis python=3.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仓库!建议添加到.gitignore

3. 数据获取与清洗

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_manager=SpotifyOAuth( scope=scope, client_id=config['SPOTIPY_CLIENT_ID'], client_secret=config['SPOTIPY_CLIENT_SECRET'], redirect_uri=config['SPOTIPY_REDIRECT_URI'] ))

这个scope参数表示我们需要三种权限:

  • 读取收藏歌曲
  • 读取个人排行榜
  • 读取近期播放历史

首次运行时会自动打开浏览器完成授权。

3.2 获取核心听歌数据

创建data_fetcher.py

def get_recent_tracks(sp, limit=50): """获取最近播放的歌曲""" results = sp.current_user_recently_played(limit=limit) 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, type='tracks', time_range='medium_term', limit=50): """获取排行榜数据""" return sp.current_user_top_items( type=type, time_range=time_range, limit=limit )

3.3 获取音频特征数据

Spotify为每首歌提供了丰富的音频特征:

def get_audio_features(sp, track_ids): """批量获取音频特征""" features = [] for i in range(0, len(track_ids), 50): batch = track_ids[i:i+50] features += sp.audio_features(batch) return features

关键音频特征说明:

  • danceability:节奏感 (0-1)
  • energy:能量感 (0-1)
  • valence:情绪积极度 (0-1)
  • tempo:BPM速度
  • 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( kind='bar', 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), endpoint=False).tolist() angles += angles[:1] fig, ax = plt.subplots(figsize=(6,6), subplot_kw={'polar': True}) ax.fill(angles, stats, color='#1DB954', alpha=0.25) ax.plot(angles, stats, color='#1DB954', linewidth=2) ax.set_xticks(angles[:-1]) ax.set_xticklabels(categories) ax.set_title('你的音乐DNA', pad=20) 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(i+1, 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], weight=1) # 绘制网络 plt.figure(figsize=(12,12)) pos = nx.spring_layout(G) nx.draw_networkx_nodes(G, pos, node_size=50) nx.draw_networkx_edges(G, pos, alpha=0.2) nx.draw_networkx_labels(G, pos, font_size=8) 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']] ], axis=1) # 计算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, limit=10): return sp.recommendations( seed_tracks=seed_tracks, limit=limit, target_danceability=0.7, target_energy=0.6 )

5.3 导出分析报告

使用Jinja2生成HTML报告:

from jinja2 import Environment, FileSystemLoader def generate_report(analysis_results): env = Environment(loader=FileSystemLoader('.')) template = env.get_template('report_template.html') html = template.render( top_artists=analysis_results['top_artists'], top_tracks=analysis_results['top_tracks'], audio_features=analysis_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) raise

6.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 conn

6.3 提升分析深度的技巧

  1. 结合外部数据

    • 用last.fm API补充标签数据
    • 接入天气API分析天气对听歌影响
  2. 高级分析方法

    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_clusters=3) features_df['cluster'] = kmeans.fit_predict(X) return features_df
  3. 自动化部署方案

    • 使用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()

这个项目最有趣的部分在于,随着你持续运行分析脚本,会逐渐发现一些自己都没意识到的听歌模式。比如我自己就发现,每逢阴雨天总会不自觉地播放更多独立民谣,而周五下午的能量饮料时间则固定会出现电子音乐——这些隐藏在数据中的行为模式,才是音乐分析最迷人的地方。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询