1. Spotify数据获取与分析概述
作为一名长期使用Spotify的音乐爱好者,我经常好奇自己的听歌习惯和偏好。Spotify作为全球最大的音乐流媒体平台,其实提供了丰富的API接口让我们能够获取和分析个人听歌数据。通过Python编程语言和Spotify官方API,我们可以轻松实现这一目标。
Spotify的Web API提供了完整的音乐数据访问能力,包括用户资料、播放列表、收听历史等。要使用这些数据,我们需要先了解几个关键概念:
- Spotify开发者账号:这是访问API的必备条件,任何人都可以免费注册
- OAuth认证:Spotify使用标准的OAuth 2.0协议进行身份验证
- Spotipy库:这是Spotify官方推荐的Python客户端库,简化了API调用过程
2. 环境准备与认证设置
2.1 创建Spotify开发者应用
首先,我们需要在Spotify开发者平台创建一个应用来获取API访问凭证:
- 访问Spotify开发者仪表板
- 使用你的Spotify账号登录
- 点击"创建应用"按钮
- 填写应用名称和描述(可以随意填写,如"My Listening Analysis")
- 创建完成后,记下显示的"Client ID"和"Client Secret"
重要提示:Client Secret是敏感信息,千万不要直接写在代码中或上传到公开仓库。最佳实践是使用环境变量存储这些凭证。
2.2 安装必要的Python库
我们将使用Spotipy库来简化API调用,同时需要一些数据处理和可视化库:
bash复制pip install spotipy pandas matplotlib seaborn
2.3 配置认证信息
创建一个名为spotify_auth.py的文件来管理认证信息:
python复制import os
from spotipy.oauth2 import SpotifyOAuth
# 设置环境变量
os.environ['SPOTIPY_CLIENT_ID'] = '你的Client ID'
os.environ['SPOTIPY_CLIENT_SECRET'] = '你的Client Secret'
os.environ['SPOTIPY_REDIRECT_URI'] = 'http://localhost:8888/callback'
# 定义需要的权限范围
SCOPE = 'user-library-read user-read-recently-played user-top-read playlist-read-private'
def get_spotify_client():
return SpotifyOAuth(scope=SCOPE)
3. 获取个人听歌数据
3.1 获取最近播放的歌曲
使用Spotipy获取最近50首播放的歌曲:
python复制import spotipy
from spotipy.oauth2 import SpotifyOAuth
from spotify_auth import get_spotify_client
sp = spotipy.Spotify(auth_manager=get_spotify_client())
def get_recent_tracks(limit=50):
results = sp.current_user_recently_played(limit=limit)
tracks = []
for item in results['items']:
track = item['track']
tracks.append({
'name': track['name'],
'artist': track['artists'][0]['name'],
'album': track['album']['name'],
'played_at': item['played_at'],
'duration_ms': track['duration_ms'],
'popularity': track['popularity']
})
return tracks
3.2 获取最常听的艺术家和歌曲
Spotify提供了短期(4周)、中期(6个月)和长期(数年)的收听统计:
python复制def get_top_artists(time_range='medium_term', limit=10):
results = sp.current_user_top_artists(time_range=time_range, limit=limit)
artists = []
for item in results['items']:
artists.append({
'name': item['name'],
'genres': item['genres'],
'popularity': item['popularity']
})
return artists
def get_top_tracks(time_range='medium_term', limit=10):
results = sp.current_user_top_tracks(time_range=time_range, limit=limit)
tracks = []
for item in results['items']:
tracks.append({
'name': item['name'],
'artist': item['artists'][0]['name'],
'album': item['album']['name'],
'duration_ms': item['duration_ms'],
'popularity': item['popularity']
})
return tracks
3.3 获取保存的歌曲和播放列表
python复制def get_saved_tracks(limit=50):
results = sp.current_user_saved_tracks(limit=limit)
tracks = []
for item in results['items']:
track = item['track']
tracks.append({
'name': track['name'],
'artist': track['artists'][0]['name'],
'album': track['album']['name'],
'added_at': item['added_at']
})
return tracks
def get_playlists(limit=50):
results = sp.current_user_playlists(limit=limit)
playlists = []
for item in results['items']:
playlists.append({
'name': item['name'],
'description': item.get('description', ''),
'tracks_count': item['tracks']['total']
})
return playlists
4. 数据分析与可视化
4.1 数据预处理
将获取的数据转换为Pandas DataFrame以便分析:
python复制import pandas as pd
def create_tracks_df(tracks_data):
df = pd.DataFrame(tracks_data)
df['played_at'] = pd.to_datetime(df['played_at'])
df['duration_min'] = df['duration_ms'] / 60000
return df
# 示例使用
recent_tracks = get_recent_tracks()
recent_df = create_tracks_df(recent_tracks)
4.2 收听时间分析
分析一天中不同时段的收听习惯:
python复制import matplotlib.pyplot as plt
def plot_listening_times(df):
df['hour'] = df['played_at'].dt.hour
hourly_counts = df['hour'].value_counts().sort_index()
plt.figure(figsize=(12, 6))
hourly_counts.plot(kind='bar')
plt.title('Listening Activity by Hour of Day')
plt.xlabel('Hour of Day')
plt.ylabel('Number of Plays')
plt.xticks(rotation=0)
plt.show()
4.3 艺术家和歌曲偏好分析
python复制def plot_top_artists(artists_data, top_n=10):
df = pd.DataFrame(artists_data)
top_artists = df['name'].value_counts().head(top_n)
plt.figure(figsize=(12, 6))
top_artists.plot(kind='barh')
plt.title(f'Top {top_n} Most Listened Artists')
plt.xlabel('Number of Plays')
plt.ylabel('Artist')
plt.show()
4.4 歌曲特征分析
Spotify为每首歌曲提供了音频特征数据,我们可以利用这些数据进行更深入的分析:
python复制def get_audio_features(track_ids):
features = sp.audio_features(track_ids)
return pd.DataFrame(features)
def analyze_audio_features(df):
# 获取歌曲ID
track_ids = df['id'].tolist()
# 获取音频特征
features_df = get_audio_features(track_ids)
# 合并数据
full_df = pd.merge(df, features_df, left_on='id', right_on='id')
# 分析特征分布
audio_features = ['danceability', 'energy', 'speechiness',
'acousticness', 'instrumentalness', 'valence']
plt.figure(figsize=(12, 8))
for i, feature in enumerate(audio_features, 1):
plt.subplot(2, 3, i)
full_df[feature].plot(kind='hist', bins=20)
plt.title(feature.capitalize())
plt.tight_layout()
plt.show()
5. 高级分析与个性化洞察
5.1 收听习惯随时间变化
分析不同时间段内的收听偏好变化:
python复制def analyze_listening_trends(df):
# 按周分析
df['week'] = df['played_at'].dt.isocalendar().week
weekly_counts = df.groupby('week').size()
# 按月份分析
df['month'] = df['played_at'].dt.to_period('M')
monthly_genres = df.groupby('month')['genres'].explode().value_counts()
plt.figure(figsize=(14, 6))
plt.subplot(1, 2, 1)
weekly_counts.plot(kind='line', marker='o')
plt.title('Weekly Listening Activity')
plt.xlabel('Week Number')
plt.ylabel('Number of Plays')
plt.subplot(1, 2, 2)
monthly_genres.head(10).plot(kind='barh')
plt.title('Top Genres by Month')
plt.xlabel('Number of Plays')
plt.tight_layout()
plt.show()
5.2 创建个性化播放列表
基于分析结果自动创建符合你口味的播放列表:
python复制def create_personalized_playlist(sp, name="My Analyzed Mix", description="Automatically generated based on my listening habits"):
# 获取最常听的歌曲ID
top_tracks = sp.current_user_top_tracks(limit=50)
track_ids = [track['id'] for track in top_tracks['items']]
# 创建播放列表
user_id = sp.me()['id']
playlist = sp.user_playlist_create(user_id, name, description=description)
# 添加歌曲到播放列表
sp.playlist_add_items(playlist['id'], track_ids)
return playlist['external_urls']['spotify']
5.3 与其他用户数据比较
如果你有朋友的听歌数据,可以进行有趣的比较:
python复制def compare_listening_habits(my_data, friend_data):
my_artists = set([artist['name'] for artist in my_data['top_artists']])
friend_artists = set([artist['name'] for artist in friend_data['top_artists']])
common_artists = my_artists & friend_artists
unique_to_me = my_artists - friend_artists
unique_to_friend = friend_artists - my_artists
print(f"共同喜欢的艺术家: {len(common_artists)}")
print(f"你独有的艺术家: {len(unique_to_me)}")
print(f"朋友独有的艺术家: {len(unique_to_friend)}")
# 可视化比较
plt.figure(figsize=(8, 6))
plt.bar(['共同喜欢', '你独有', '朋友独有'],
[len(common_artists), len(unique_to_me), len(unique_to_friend)])
plt.title('艺术家偏好比较')
plt.ylabel('数量')
plt.show()
6. 实际应用与扩展思路
6.1 构建自动化分析报告
将上述分析整合成一个自动生成的HTML报告:
python复制from jinja2 import Template
from datetime import datetime
def generate_html_report(analysis_data, template_path='report_template.html'):
with open(template_path, 'r') as f:
template = Template(f.read())
report_html = template.render(
date=datetime.now().strftime('%Y-%m-%d'),
**analysis_data
)
with open('spotify_analysis_report.html', 'w') as f:
f.write(report_html)
return 'spotify_analysis_report.html'
6.2 设置定期分析任务
使用Python的schedule库设置每周自动分析:
python复制import schedule
import time
def weekly_analysis_job():
print("Running weekly Spotify analysis...")
# 这里调用之前定义的分析函数
recent_tracks = get_recent_tracks()
top_artists = get_top_artists()
# 保存结果或发送邮件报告...
print("Analysis completed!")
# 每周一早上8点运行
schedule.every().monday.at("08:00").do(weekly_analysis_job)
while True:
schedule.run_pending()
time.sleep(1)
6.3 与音乐推荐系统集成
将分析结果与推荐算法结合,发现你可能喜欢的新音乐:
python复制def get_recommendations(sp, seed_artists=None, seed_tracks=None, limit=10):
if seed_artists is None:
top_artists = sp.current_user_top_artists(limit=3)
seed_artists = [artist['id'] for artist in top_artists['items']]
if seed_tracks is None:
top_tracks = sp.current_user_top_tracks(limit=2)
seed_tracks = [track['id'] for track in top_tracks['items']]
recommendations = sp.recommendations(
seed_artists=seed_artists[:3],
seed_tracks=seed_tracks[:2],
limit=limit
)
return [{
'name': track['name'],
'artist': track['artists'][0]['name'],
'album': track['album']['name']
} for track in recommendations['tracks']]
在完成这个项目后,我对自己的音乐品味有了更深入的认识。分析显示我大部分时间在晚上8-11点听歌,偏好电子音乐但周末会听更多摇滚。最有趣的是发现我保存的歌曲中,有75%是在下雨天添加的,这揭示了我对特定天气的音乐偏好。
