尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python实战:利用Spotify API分析个人音乐偏好
1. 项目概述用Python挖掘你的Spotify音乐DNA作为一名长期使用Spotify的音乐爱好者兼Python开发者我最近发现了一个有趣的现象虽然平台每年都会推出年度回顾功能但那些预制报表始终无法满足我对听歌数据的深度挖掘需求。于是我用Python构建了一套完整的分析工具链不仅能还原官方报告的所有维度还能发现许多隐藏的音乐偏好模式。这个项目的核心价值在于通过Spotify开放的Web API我们可以获取到包括播放频率、歌曲特征、时间分布等在内的完整听歌记录。结合Python生态中丰富的数据分析工具每个人都能像专业音乐分析师一样从多个角度解读自己的听觉习惯。2. 环境准备与API接入2.1 创建Spotify开发者应用首先需要在 Spotify开发者仪表板 新建应用点击Create an App按钮填写应用名称如My Listening Analytics记录下自动生成的Client ID和Client Secret重要提示在应用设置中必须添加回调地址本地开发建议使用http://localhost:8888/callback2.2 安装必要的Python库推荐使用conda创建独立环境conda create -n spotify-analysis python3.9 conda activate spotify-analysis pip install spotipy pandas matplotlib seaborn sklearn关键库说明spotipy官方推荐的Python SDKpandas数据处理核心工具matplotlib/seaborn可视化双雄sklearn用于高级聚类分析2.3 实现OAuth认证流程建立auth_manager.py处理认证逻辑import spotipy from spotipy.oauth2 import SpotifyOAuth def get_spotify_client(): return spotipy.Spotify(auth_managerSpotifyOAuth( client_id你的CLIENT_ID, client_secret你的CLIENT_SECRET, redirect_urihttp://localhost:8888/callback, scopeuser-library-read user-top-read user-read-recently-played ))3. 数据采集与清洗3.1 获取核心听歌数据通过Spotify API可以获取多种数据类型建议分批采集def fetch_all_data(sp): # 最近50条播放记录 recently_played sp.current_user_recently_played(limit50) # 收藏的歌曲最多50首 saved_tracks sp.current_user_saved_tracks(limit50) # 长期听歌偏好分短期/中期/长期 top_tracks_short sp.current_user_top_tracks(time_rangeshort_term, limit50) top_tracks_medium sp.current_user_top_tracks(time_rangemedium_term, limit50) top_tracks_long sp.current_user_top_tracks(time_rangelong_term, limit50) return { recently_played: recently_played, saved_tracks: saved_tracks, top_tracks: { short_term: top_tracks_short, medium_term: top_tracks_medium, long_term: top_tracks_long } }3.2 数据标准化处理原始API返回的JSON结构复杂需要转换为扁平化表格def flatten_track_data(raw_data): tracks [] for item in raw_data[items]: track item[track] if track in item else item features { id: track[id], name: track[name], artist: , .join([a[name] for a in track[artists]]), duration_ms: track[duration_ms], popularity: track[popularity], played_at: item.get(played_at, None), saved_at: item.get(added_at, None) } tracks.append(features) return pd.DataFrame(tracks)3.3 补充音频特征数据Spotify为每首歌曲提供了专业的音频分析def add_audio_features(sp, df): features sp.audio_features(df[id].tolist()) feature_cols [ danceability, energy, key, loudness, mode, speechiness, acousticness, instrumentalness, liveness, valence, tempo ] for f in features: for col in feature_cols: df.loc[df[id] f[id], col] f[col] return df4. 多维分析实战4.1 基础统计指标先快速生成描述性统计print(df[[danceability, energy, valence, tempo]].describe())典型输出示例danceability energy valence tempo count 150.000000 150.000000 150.000000 150.000000 mean 0.654213 0.672133 0.513200 122.453867 std 0.143885 0.198762 0.236745 28.771422 min 0.285000 0.038700 0.037900 65.958000 25% 0.563250 0.543250 0.331750 100.027250 50% 0.672000 0.712000 0.518000 122.936000 75% 0.761750 0.837750 0.704750 140.052750 max 0.943000 0.983000 0.965000 206.0070004.2 时间维度分析分析不同时段的听歌偏好变化# 转换时间戳 df[hour] pd.to_datetime(df[played_at]).dt.hour # 绘制24小时听歌分布 plt.figure(figsize(12,6)) sns.countplot(xhour, datadf, paletteviridis) plt.title(Hourly Listening Distribution) plt.show()4.3 音乐特征雷达图通过雷达图直观展示音乐偏好def plot_radar_chart(df): features [danceability, energy, speechiness, acousticness, instrumentalness, liveness, valence] stats df[features].mean().values angles np.linspace(0, 2*np.pi, len(features), endpointFalse) stats np.concatenate((stats,[stats[0]])) angles np.concatenate((angles,[angles[0]])) features.append(features[0]) fig plt.figure(figsize(8,8)) ax fig.add_subplot(111, polarTrue) ax.plot(angles, stats, o-, linewidth2) ax.fill(angles, stats, alpha0.25) ax.set_thetagrids(angles * 180/np.pi, features) ax.set_title(Audio Features Radar Chart, y1.1) plt.show()5. 高级分析技巧5.1 基于K-Means的音乐聚类将歌曲按特征自动分组from sklearn.cluster import KMeans def cluster_tracks(df, n_clusters4): features df[[danceability, energy, valence, tempo]] features (features - features.mean()) / features.std() kmeans KMeans(n_clustersn_clusters, random_state42) df[cluster] kmeans.fit_predict(features) # 可视化聚类结果 plt.figure(figsize(10,6)) sns.scatterplot(xvalence, yenergy, huecluster, datadf, paletteviridis, s100) plt.title(Track Clusters by Audio Features) plt.show() return df5.2 歌手影响力网络图分析不同歌手在你的播放列表中的关联程度import networkx as nx def build_artist_network(df): # 创建共现矩阵 artists df[artist].str.split(, ).explode().unique() co_matrix pd.DataFrame(0, indexartists, columnsartists) for _, row in df.iterrows(): track_artists row[artist].split(, ) for a1 in track_artists: for a2 in track_artists: if a1 ! a2: co_matrix.loc[a1, a2] 1 # 构建网络图 G nx.Graph() for a1 in artists: for a2 in artists: if co_matrix.loc[a1, a2] 0: G.add_edge(a1, a2, weightco_matrix.loc[a1, a2]) # 可视化 plt.figure(figsize(15,15)) pos nx.spring_layout(G, k0.3) 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(Artist Co-occurrence Network) plt.show()6. 实战经验与避坑指南6.1 API调用优化技巧请求限速处理from time import sleep from random import uniform 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)) sleep(retry_after uniform(0.5, 1.5)) return safe_api_call(func, *args, **kwargs) raise数据缓存策略import json from pathlib import Path def cached_api_call(cache_file, func, *args, **kwargs): cache_path Path(fcache/{cache_file}) if cache_path.exists(): with open(cache_path) as f: return json.load(f) data func(*args, **kwargs) cache_path.parent.mkdir(exist_okTrue) with open(cache_path, w) as f: json.dump(data, f) return data6.2 常见问题解决方案问题1spotipy.oauth2.SpotifyOauthError: Invalid redirect URI➔ 检查开发者仪表板设置的回调地址必须与代码中的redirect_uri完全一致包括末尾斜杠问题2获取的播放记录远少于实际播放量➔ Spotify API目前只返回最近50条播放记录如需更完整数据需要定期自动采集问题3音频特征数据存在NaN值➔ 通常是因为某些区域限制的曲目建议过滤处理df df.dropna(subset[danceability, energy])6.3 可视化优化建议动态交互图表import plotly.express as px fig px.scatter_3d(df, xdanceability, yenergy, zvalence, colorcluster, hover_namename, hover_data[artist, tempo]) fig.show()时间序列热力图# 按小时和星期分析播放模式 df[weekday] pd.to_datetime(df[played_at]).dt.day_name() hour_week df.groupby([hour, weekday]).size().unstack() plt.figure(figsize(12,8)) sns.heatmap(hour_week, cmapYlGnBu, annotTrue, fmtd) plt.title(Listening Pattern by Hour and Weekday) plt.show()7. 项目扩展方向自动化定期采集import schedule import time def daily_job(): data fetch_all_data(sp) timestamp datetime.now().strftime(%Y%m%d_%H%M%S) with open(fdata/history_{timestamp}.json, w) as f: json.dump(data, f) schedule.every().day.at(23:59).do(daily_job) while True: schedule.run_pending() time.sleep(60)音乐推荐引擎from sklearn.neighbors import NearestNeighbors def build_recommender(df): features df[[danceability, energy, valence]] nn NearestNeighbors(n_neighbors5).fit(features) return nn def recommend_similar(df, track_id, nn_model): track_features df[df[id]track_id][[danceability,energy,valence]] distances, indices nn_model.kneighbors(track_features) return df.iloc[indices[0]]情绪波动分析def mood_analysis(df): df[mood] pd.cut(df[valence], bins[0,0.3,0.7,1], labels[低情绪,中性,高情绪]) plt.figure(figsize(10,6)) sns.countplot(xhour, huemood, datadf, palettecoolwarm) plt.title(Mood Distribution by Hour) plt.show()
RELATED

相关推荐

AI智能体持久化运行安全评估:HarnessSafe框架与实践

AI智能体持久化运行安全评估:HarnessSafe框架与实践

1. 项目概述:当智能体“持久化”,我们如何评估其安全性? 最近和几个做AI智能体(Agent)和自动化流程的朋友聊天,大家不约而同地提到了一个痛点:我们设计的智能体,在单次、独立的运行中…

📅 2026/10/10 19:13:49
PictureBox图像处理:轻量级解决方案与实战技巧

PictureBox图像处理:轻量级解决方案与实战技巧

1. 为什么PictureBox值得成为你的图像处理利器在Windows Forms应用开发中,PictureBox控件就像一位默默无闻的瑞士军刀。这个看似简单的控件,实际上内置了多种图像处理能力,从基础的显示功能到高级的像素操作都能胜任。我曾在多个工业检测项目…

📅 2026/9/19 20:45:31
零基础3步上手ZLMediaKit流媒体服务器:一网打尽RTSP、RTMP与WebRTC的完整实践指南

零基础3步上手ZLMediaKit流媒体服务器:一网打尽RTSP、RTMP与WebRTC的完整实践指南

零基础3步上手ZLMediaKit流媒体服务器:一网打尽RTSP、RTMP与WebRTC的完整实践指南 【免费下载链接】ZLMediaKit WebRTC/RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/HTTP-TS/HTTP-fMP4/WebSocket-TS/WebSocket-fMP4/GB28181/SRT/STUN/TURN server and client framew…

📅 2026/9/13 21:54:18
MORE NEWS

更多资讯

📰

研究生论文降AI率实战:千笔AI与锐智AI对比评测

研究生阶段最耗精力的其实不是找创新点,而是把“像AI写的”变成“像人写的”。导师看一眼初稿,眉头一皱说“语言风格太规整了”,这就是在提醒你:AI痕迹太重了。现在很多学位论文和期刊投稿除了查重,还会过一遍AI检测。…

📰

Java枚举深度解析:从底层原理到实战玩法与避坑指南

说起来有点不好意思,我见过不少Java开发,写了好几年代码,被问到“enum到底是个什么东西”时,第一反应还是“一组常量嘛”,然后就没有然后了。enum在Java里确实太容易让人小看,因为它写起来太简单了&#xf…

📰

Dify 124万行代码背后:把 AI 工作流从“画得出”跑到“稳得住”的 TaoToken 实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

AI 读财报翻车现场:Xing4.0 的数字幻觉怎么治

AI 读财报翻车现场:Xing4.0 的数字幻觉怎么治 【免费下载链接】Xing4.0-29B-A4B Xing4.0-29B-A4B 是中电信人工智能科技有限公司研发的星辰语义大模型系列(原 TeleChat)新一代模型。模型总参数量 29B,激活参数仅 4B,原…

📰

Codex 官方安装与国内使用教程:Windows/macOS/Linux + codex login 一次跑通(TaoToken 统一 Key 版)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

agency-agents架构实战:调度与执行分离的设计与实现

1. 从“agency-agents”这个标题说起:它到底在解决什么问题第一次看到“agency-agents”这个组合词,我脑子里跳出来的第一反应是:这大概率不是一个单纯的工具库,而是一套围绕“代理”和“代理机构”之间关系做文章的东西。拆开看&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬