☰
Python分析Spotify听歌数据:从API获取到高级可视化
2026/10/15 9:58:50 网站建设 项目流程

1. 项目概述:从数据角度重新认识你的音乐品味

作为一个长期使用Spotify的音乐爱好者,我发现自己经常在年底收到平台的"年度回顾"报告时感到惊喜——"原来我今年听了这么多遍这首歌?"。这种数据驱动的自我发现体验让我萌生了一个想法:为什么不自己动手分析这些数据呢?于是就有了这个用Python解析个人Spotify听歌数据的项目。

这个项目的核心价值在于,它让你摆脱平台预设的分析框架,完全按照个人兴趣来探索自己的音乐行为模式。比如你可以发现:

  • 每周不同时段的音乐偏好变化
  • 特定情绪状态下的歌曲选择规律
  • 长期音乐品味的演变轨迹
  • 甚至预测下一首可能会喜欢的歌曲

提示:Spotify官方API提供了6个月内的详细收听记录,但通过数据请求可以获取完整的收听历史(需要特别申请)。

2. 环境准备与数据获取

2.1 创建Spotify开发者应用

首先需要在 Spotify开发者平台 创建一个应用来获取API凭证:

  1. 登录后点击"Create an App"
  2. 填写应用名称和描述(可以随意填写)
  3. 记录下生成的Client ID和Client Secret
  4. 在设置中添加回调URL(本地开发可以用http://localhost:8080)
# 配置示例 SPOTIFY_CLIENT_ID = 'your_client_id' SPOTIFY_CLIENT_SECRET = 'your_client_secret' REDIRECT_URI = 'http://localhost:8080'

2.2 获取个人收听数据

Spotify提供两种数据获取方式:

  1. 通过API获取近期数据(最近6个月):

    • 需要用户授权
    • 可以实时获取
    • 包含播放次数、时间戳等详细信息
  2. 请求完整数据副本(可能需要30天):

    • 通过 隐私设置页面 申请
    • 包含所有历史收听记录
    • 数据以JSON格式提供
# 使用spotipy库进行认证 import spotipy from spotipy.oauth2 import SpotifyOAuth scope = "user-read-recently-played user-top-read" sp = spotipy.Spotify(auth_manager=SpotifyOAuth( client_id=SPOTIFY_CLIENT_ID, client_secret=SPOTIFY_CLIENT_SECRET, redirect_uri=REDIRECT_URI, scope=scope))

3. 数据分析核心模块实现

3.1 基础数据清洗与转换

原始数据通常需要经过以下处理:

def clean_spotify_data(raw_data): # 转换时间戳 raw_data['played_at'] = pd.to_datetime(raw_data['played_at']) # 提取音频特征 track_ids = raw_data['track_id'].tolist() audio_features = [] for i in range(0, len(track_ids), 50): batch = track_ids[i:i+50] audio_features.extend(sp.audio_features(batch)) # 合并数据 features_df = pd.DataFrame(audio_features) merged_df = pd.merge(raw_data, features_df, left_on='track_id', right_on='id') # 添加衍生特征 merged_df['hour_of_day'] = merged_df['played_at'].dt.hour merged_df['day_of_week'] = merged_df['played_at'].dt.dayofweek merged_df['is_weekend'] = merged_df['day_of_week'].isin([5,6]).astype(int) return merged_df

3.2 音乐特征分析

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

特征说明分析价值
danceability舞蹈性识别运动时的音乐偏好
energy能量感分析不同时段的能量需求
valence愉悦度情绪状态推断
tempo速度(BPM)活动强度关联分析
speechiness语言含量学习/工作时的偏好
acousticness原声程度品味演变分析
def analyze_audio_features(df): # 时段特征分析 time_features = df.groupby('hour_of_day')[ ['danceability', 'energy', 'valence'] ].mean().reset_index() # 周特征分析 weekly_pattern = df.groupby('day_of_week')[ 'tempo' ].agg(['mean', 'count']).reset_index() # 情绪聚类 from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=3) df['mood_cluster'] = kmeans.fit_predict(df[['valence', 'energy']]) return { 'time_features': time_features, 'weekly_pattern': weekly_pattern, 'mood_clusters': kmeans.cluster_centers_ }

3.3 收听行为可视化

使用Plotly创建交互式可视化:

import plotly.express as px def create_heatmap(df): fig = px.density_heatmap( df, x='hour_of_day', y='day_of_week', z='danceability', histfunc='avg', title='一周内舞蹈性偏好变化' ) fig.update_layout( yaxis_title="星期几", xaxis_title="小时", yaxis=dict(tickvals=list(range(7)), ticktext=['周一','周二','周三','周四','周五','周六','周日']) ) return fig def create_mood_scatter(df): fig = px.scatter( df, x='valence', y='energy', color='mood_cluster', hover_data=['track_name'], title='歌曲情绪分布' ) return fig

4. 高级分析技巧

4.1 音乐品味演变分析

通过时间序列分析观察音乐品味的变化:

def analyze_temporal_trends(df): # 按月聚合 monthly = df.set_index('played_at').resample('M')[ ['danceability', 'energy', 'valence'] ].mean() # 滚动平均平滑 smooth = monthly.rolling(window=3).mean() # 绘制趋势线 fig = px.line(smooth, title="音乐特征月度变化趋势") return fig

4.2 艺人网络关系图

分析你经常一起听的艺人之间的关系:

import networkx as nx def create_artist_network(df): # 创建共现矩阵 artist_pairs = df.groupby('played_at')['artist_name'].unique().apply( lambda x: list(itertools.combinations(x, 2)) if len(x)>1 else [] ).explode().dropna() # 构建图 G = nx.Graph() for pair in artist_pairs: if G.has_edge(*pair): G.edges[pair]['weight'] += 1 else: G.add_edge(*pair, weight=1) # 可视化 pos = nx.spring_layout(G) nx.draw(G, pos, with_labels=True, edge_color=[d['weight'] for _,_,d in G.edges(data=True)])

4.3 播放预测模型

基于历史数据预测未来可能喜欢的歌曲:

from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split def build_recommendation_model(df): # 标记常听歌曲 play_counts = df['track_id'].value_counts() df['is_frequent'] = df['track_id'].apply( lambda x: 1 if play_counts[x] > play_counts.quantile(0.75) else 0) # 准备特征 features = ['danceability', 'energy', 'valence', 'tempo', 'hour_of_day', 'day_of_week'] X = df[features] y = df['is_frequent'] # 训练模型 X_train, X_test, y_train, y_test = train_test_split(X, y) model = RandomForestClassifier() model.fit(X_train, y_train) return model

5. 实战经验与避坑指南

5.1 数据获取常见问题

  1. API速率限制:

    • Spotify API每分钟限制100次请求
    • 批量获取音频特征时需分块处理(建议50首/批)
    • 添加适当的sleep间隔(0.5-1秒)
  2. 历史数据不完整:

    • 官方API只提供最近6个月数据
    • 完整数据需要单独申请,处理时间可能长达30天
    • 建议定期备份自己的收听数据
  3. 认证令牌过期:

    • 访问令牌1小时后失效
    • 使用刷新令牌自动获取新令牌
    • 实现令牌持久化存储
# 令牌刷新示例 def get_refreshed_token(): auth_manager = SpotifyOAuth( client_id=SPOTIFY_CLIENT_ID, client_secret=SPOTIFY_CLIENT_SECRET, redirect_uri=REDIRECT_URI, scope=scope) if not auth_manager.validate_token(auth_manager.get_cached_token()): auth_manager.refresh_access_token(auth_manager.get_cached_token()['refresh_token']) return auth_manager.get_access_token()

5.2 分析技巧进阶

  1. 时段分析的黄金分割:

    • 不要简单按小时分析,尝试划分:
      • 早晨通勤(7-9)
      • 工作时间(9-12, 13-17)
      • 晚间放松(18-22)
      • 深夜时段(23-3)
  2. 情绪四象限法:

    • 将valence和energy组合为:
      • 高能快乐(右上)
      • 高能愤怒(右下)
      • 低能悲伤(左下)
      • 低能平静(左上)
  3. 艺人影响力指数:

    def calculate_artist_impact(df): play_counts = df['artist_name'].value_counts() recency = (pd.Timestamp.now() - df.groupby('artist_name')['played_at'].max()).dt.days impact = play_counts / (recency + 1) # +1避免除零 return impact.sort_values(ascending=False)

5.3 可视化优化技巧

  1. 颜色主题选择:

    • 情绪分析使用红色(愤怒)-黄色(快乐)-蓝色(悲伤)渐变
    • 时段分析使用日出到日落的颜色渐变
    • 艺人网络使用Spotify品牌绿作为主色
  2. 交互式提示设计:

    fig.update_traces( hovertemplate="<b>%{customdata[0]}</b><br>" "艺人: %{customdata[1]}<br>" "播放时间: %{customdata[2]}<br>" "舞蹈性: %{x:.2f}<br>" "能量: %{y:.2f}<extra></extra>" )
  3. 动态时间轴:

    fig = px.scatter( df, x='valence', y='energy', animation_frame=df['played_at'].dt.strftime('%Y-%m'), range_x=[0,1], range_y=[0,1] )

6. 项目扩展方向

6.1 实时收听仪表板

使用Dash构建实时监控面板:

import dash from dash import dcc, html app = dash.Dash(__name__) app.layout = html.Div([ dcc.Graph(id='mood-scatter'), dcc.Interval( id='interval-component', interval=60*1000, # 1分钟刷新 n_intervals=0 ) ]) @app.callback( Output('mood-scatter', 'figure'), Input('interval-component', 'n_intervals') ) def update_graph(n): recent_tracks = get_recently_played() return create_mood_scatter(recent_tracks)

6.2 自动播放列表生成

基于分析结果创建智能播放列表:

def create_mood_playlist(df, mood='calm'): mood_filters = { 'calm': (df['energy'] < 0.4) & (df['valence'] > 0.6), 'energetic': (df['energy'] > 0.7) & (df['danceability'] > 0.7), 'focus': (df['speechiness'] < 0.1) & (df['tempo'].between(50, 70)) } track_uris = df[mood_filters[mood]]['track_uri'].tolist() playlist = sp.user_playlist_create( user_id, f"我的{mood}歌单 - {datetime.now().strftime('%Y-%m-%d')}", public=False) sp.playlist_add_items(playlist['id'], track_uris[:50])

6.3 跨平台数据整合

结合Last.fm等其他平台数据:

def merge_multiple_sources(spotify_df, lastfm_df): # 统一时间格式 lastfm_df['timestamp'] = pd.to_datetime(lastfm_df['timestamp'], unit='s') # 合并数据集 merged = pd.concat([ spotify_df[['track_name', 'artist_name', 'played_at']], lastfm_df[['track_name', 'artist_name', 'timestamp']].rename( columns={'timestamp': 'played_at'}) ]) # 去重并排序 return merged.drop_duplicates().sort_values('played_at')

在完成这个项目的过程中,我发现最有意思的洞察是工作日和周末的音乐选择差异远比想象中大——周一到周五我倾向于听更多器乐和低歌词含量的音乐(可能是为了专注工作),而周末则明显偏好节奏感强的流行音乐。这种模式在数据可视化中呈现出惊人的规律性,让我开始有意识地调整不同场景下的音乐选择策略。

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

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

立即咨询