Python 网易云音乐数据分析可视化平台 Flask+ECharts 多维度分析
本项目基于 Python、Flask 及 ECharts 构建网易云音乐数据分析可视化平台。通过 Selenium 与 Requests 爬取歌单、歌曲及评论数据,存入 SQLite 数据库。系统实现情感分类、语种统计、用户画像分析及歌词词云等模块,支持多维度数据展示与交互。技术栈涵盖 Python、SQL、HTML、Bootstrap 等,为音乐平台数据分析提供可视化解决方案。

本项目基于 Python、Flask 及 ECharts 构建网易云音乐数据分析可视化平台。通过 Selenium 与 Requests 爬取歌单、歌曲及评论数据,存入 SQLite 数据库。系统实现情感分类、语种统计、用户画像分析及歌词词云等模块,支持多维度数据展示与交互。技术栈涵盖 Python、SQL、HTML、Bootstrap 等,为音乐平台数据分析提供可视化解决方案。

技术栈 采用 Python、SQL、HTML 语言开发,借助 selenium 与 request 库完成数据爬取,通过 SQLite 数据库存储数据并可在 Navicat 中查看;基于 Flask 搭建后端、Bootstrap 搭建前端,利用 ECharts 实现图表可视化,结合 pyplot、jieba、wordcloud 等库制作词云。
功能模块
项目介绍 该项目围绕网易云音乐数据展开分析与可视化,从数据爬取、清洗、存储到 Web 可视化平台搭建形成完整流程。依托多类技术栈实现歌单、歌曲、评论等多维度数据的采集与管理,通过多样化图表和词云形式呈现数据可视化结果,支持从不同维度分析数据。项目产出的分析结果可为网易云音乐平台的歌单、歌曲相关数据预测提供参考,也能为用户创建和选择优质歌单、平台提升用户粘性与优化音乐推送提供价值。
(1)数据可视化展示–情感分类统计图 包含情感分类统计图的展示、图表数据的悬浮查看、图表的刷新与下载功能,同时提供了基于情感标签分类的分析文本内容,还具备左侧导航栏的页面切换功能。

(2)系统首页–数据概况 包含歌单、歌曲、评论、热评等数据统计卡片的展示,精彩评论的展示与点赞功能,同时具备左侧导航栏的页面切换、页面刷新以及用户信息查看等功能。

(3)语种分类统计分析 包含语种分类统计图的展示、图表数据的悬浮查看、图表的刷新与下载功能,同时提供了基于语种分类的分析文本内容,还具备左侧导航栏的页面切换功能。

(4)评论区用户年龄分布图 包含评论区用户年龄分布图的展示、图表数据的悬浮查看、图表的刷新与下载功能,同时提供了基于评论区用户年龄分布的分析文本内容,还具备左侧导航栏的页面切换功能。

(5)评论区用户进村天数分布图 包含评论区用户'进村'天数分布图的展示、图表数据的查看、图表的刷新与下载功能,同时提供了基于评论区用户'进村'天数分布的分析文本内容,还具备左侧导航栏的页面切换功能。

(6)性别年龄与听歌数量分布图 包含年龄 - 听歌数散点分布图的展示、图表数据的悬浮查看、图表的刷新与下载功能,同时具备左侧导航栏的页面切换功能。

(7)歌词词云图 包含热门歌单华语歌曲歌词词云图的展示、词频统计信息的查看,同时提供了基于歌词词云图的分析文本内容,还具备左侧导航栏的页面切换功能。

(8)数据管理 包含歌单数据的表格化展示、每页展示条目数的选择、歌单信息的搜索功能,同时具备左侧导航栏的页面切换功能,可清晰呈现歌单各类核心数据信息。

一、技术栈 本项目以 Python、SQL、HTML 为核心开发语言,通过 selenium 模块与 request 库实现网易云音乐相关数据的爬取工作;采用 SQLite 数据库存储爬取的各类数据,可通过 Navicat 软件直观查看数据内容;后端基于 Flask 框架搭建,前端借助 Bootstrap 框架完成页面布局,利用 ECharts 实现各类数据图表的可视化展示,结合 pyplot、jieba、wordcloud 等库完成歌词词云图的制作。
二、功能模块
三、项目总结 本项目围绕网易云音乐数据构建了完整的分析与可视化体系,从数据爬取、清洗、存储到 Web 可视化平台搭建形成闭环。依托多元技术栈实现多维度数据的采集与管理,通过丰富的图表和词云形式完成数据可视化呈现,覆盖情感、语种、用户画像等多维度分析。项目产出的分析结果不仅能为网易云音乐平台的歌单、歌曲数据预测提供参考,也能为用户创建优质歌单、平台提升用户粘性与优化音乐推送策略提供实用价值。
from datetime import timedelta # 本来是用做时间转换的
import sqlite3 # 连接数据库
from matplotlib import pyplot as plt # 负责绘图的模块
import jieba # 提供分词、识词过滤模块
from wordcloud import WordCloud # 词云,形成有遮罩效果的图形
from PIL import Image # 图像处理,如图形虚化、验证码、图片后期处理等
import numpy as np # 矩阵运算,中文显示需要运算空间
from flask import Flask, render_template, request # Flask 框架需要渲染页面用的库
# from flask_caching import Cache # Flask 视图函数缓存,重复的数据,只需要缓存 1 次,10 分钟自动清除缓存
app = Flask(__name__)
# cache = Cache(app, config={'CACHE_TYPE': 'simple'})
@app.route('/') # 首页
def index():
# 链接数据库
conn = sqlite3.connect('data/NEC_Music.db')
cur = conn.cursor()
# 读取歌单、歌曲、评论总数、精彩评论总数
sql = '''select * from count_all'''
result_list = []
table = cur.execute(sql)
for row in table:
result_list.append(row[0])
result_list.append(row[1])
result_list.append(row[2])
result_list.append(row[3])
# 随机读取两条精彩评论
sql3 = '''select song_id,userAvatar,user_id,user_name,content,likeCount from comments_info where comment_type = 'hot_comments' and likeCount > 500 order by random() limit 4;'''
table = cur.execute(sql3)
datalist = []
row table:
data = {: row[],: row[],: row[],: row[],: row[],: row[]}
datalist.append(data)
cur.close()
conn.close()
()
render_template(, count=result_list, datalist=datalist)
():
conn = sqlite3.connect()
cur = conn.cursor()
result_list = []
table = [,,,]
column = [,,,]
index (,):
table_name = table[index]
column_name = column[index]
sql1 = .(table=table_name, column=column_name)
result = cur.execute(sql1)
count =
r result:
i r:
count = (i)
result_list.append(count)
table_name = table[]
column_name = column[]
where =
sql2 = .(table=table_name, column=column_name, where=where)
result = cur.execute(sql2)
count =
r result:
i r:
count = (i)
result_list.append(count)
sql3 =
table = cur.execute(sql3)
datalist = []
row table:
data = {: row[],: row[],: row[],: row[],: row[],: row[]}
datalist.append(data)
sql4 = .(count=result_list[])
cur.execute(sql4)
sql4 = .(count=result_list[])
cur.execute(sql4)
sql4 = .(count=result_list[])
cur.execute(sql4)
sql4 = .(count=result_list[])
cur.execute(sql4)
conn.commit()
cur.close()
conn.close()
()
render_template(, count=result_list, datalist=datalist)
():
data = {}
datalist = []
conn = sqlite3.connect()
cur = conn.cursor()
key_list = [,,,,,,,,,,,,,,,,,,,,,]
key key_list:
data[key] =
keys = .join(key_list)
sql = .(keys=keys)
result_list = cur.execute(sql)
row result_list:
data = {}
i ((row)):
data[key_list[i]] = row[i]
datalist.append(data)
cur.close()
conn.close()
d datalist:
d[]=(d[]).replace(,)
d[]= d[].replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,)
d[]=(d[]).replace(,)
d[]= d[].replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,)
render_template(, datalist=datalist)
():
data = {}
datalist = []
conn = sqlite3.connect()
cur = conn.cursor()
key_list = [,,,,,,,,,,,,,,,]
key key_list:
data[key] =
keys = .join(key_list)
sql = .(keys=keys)
result_list = cur.execute(sql)
row result_list:
data = {}
i ((row)):
data[key_list[i]] = row[i]
datalist.append(data)
cur.close()
conn.close()
d datalist:
d[]=(d[]).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,)
d[]= d[].replace(,)
render_template(, datalist=datalist)
():
data = {}
datalist = []
conn = sqlite3.connect()
cur = conn.cursor()
key_list = [,,,,,,,,,,,,,,,,,,,,,,,,,,]
key key_list:
data[key] =
keys = .join(key_list)
sql = .(keys=keys)
result_list = cur.execute(sql)
row result_list:
data = {}
i ((row)):
data[key_list[i]] = row[i]
datalist.append(data)
cur.close()
conn.close()
d datalist:
d[]= d[].replace(,)
d[]=(d[]).replace(,).replace(,)
d[]=(d[]).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,)
d[]=(d[]).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,).replace(,)
d[]= d[].replace(,)
render_template(, datalist=datalist)
():
conn = sqlite3.connect()
cur = conn.cursor()
count_list = []
count_song = []
count_play = []
count_star = []
count_share = []
count_comment = []
songs_language = [,,,,]
lan songs_language:
sql = .(lan=lan)
table = cur.execute(sql)
row table:
count_list.append(row[])
count_song.append(row[])
count_play.append(row[])
count_star.append(row[])
count_share.append(row[])
count_comment.append(row[])
cur.close()
conn.close()
render_template(, list_count=count_list, song_count=count_song,play_count=count_play, star_count=count_star, share_count=count_share, comment_count=count_comment)
():
conn = sqlite3.connect()
cur = conn.cursor()
count_list = []
count_song = []
count_play = []
count_star = []
count_share = []
count_comment = []
songs_sentiment = [,,,,,,,,,,,]
lan songs_sentiment:
sql = .(lan=lan)
table = cur.execute(sql)
row table:
count_list.append(row[])
count_song.append(row[])
count_play.append(row[])
count_star.append(row[])
count_share.append(row[])
count_comment.append(row[])
cur.close()
conn.close()
render_template(, list_count=count_list, song_count=count_song,play_count=count_play, star_count=count_star, share_count=count_share, comment_count=count_comment)
():
conn = sqlite3.connect()
cur = conn.cursor()
age = []
age_count = []
sql1 =
table1 = cur.execute(sql1)
row table1:
age.append(row[])
age_count.append(row[])
cur.close()
conn.close()
render_template(, age=age, age_count=age_count)
():
conn = sqlite3.connect()
cur = conn.cursor()
days = []
days_count = []
sql2 =
table2 = cur.execute(sql2)
row table2:
days.append(row[])
days_count.append(row[])
cur.close()
conn.close()
render_template(, days=days, days_count=days_count)
():
conn = sqlite3.connect()
cur = conn.cursor()
male_age_listen = []
female_age_listen = []
sql1 =
sql2 =
table1 = cur.execute(sql1)
row table1:
male_age_listen.append([row[], row[]])
table2 = cur.execute(sql2)
row table2:
female_age_listen.append([row[], row[]])
cur.close()
conn.close()
render_template(, male=male_age_listen, female=female_age_listen)
():
word_frequency =
conn = sqlite3.connect()
cur = conn.cursor()
sql =
table = cur.execute(sql)
row table:
word_frequency = row[]
cur.close()
conn.close()
img_url =
render_template(, img_url=img_url, word_frequency=word_frequency)
():
conn = sqlite3.connect()
cur = conn.cursor()
sql =
text =
table = cur.execute(sql)
lyric table:
clean_text = lyric[]
clean_text = clean_text.replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,)
text += clean_text
cur.close()
conn.close()
()
lyric_cut = jieba.cut(text)
lyric_str = .join(lyric_cut)
word_frequency = (lyric_str)
img = Image.()
img_array = np.array(img)
wc = WordCloud(
background_color=,
mask=img_array,
font_path=)
wc.generate_from_text(lyric_str)
()
conn = sqlite3.connect()
cur = conn.cursor()
sql = .(word_rate=word_frequency)
cur.execute(sql)
conn.commit()
cur.close()
conn.close()
()
fig = plt.figure()
plt.imshow(wc)
plt.axis()
plt.savefig(+(word_frequency)+, dpi=)
()
img_url = +(word_frequency)+
render_template(, img_url=img_url, word_frequency=word_frequency)
():
word_frequency =
conn = sqlite3.connect()
cur = conn.cursor()
sql =
table = cur.execute(sql)
row table:
word_frequency = row[]
cur.close()
conn.close()
img_url =
render_template(, img_url=img_url, word_frequency=word_frequency)
():
conn = sqlite3.connect()
cur = conn.cursor()
sql =
text =
table = cur.execute(sql)
lyric table:
clean_text = lyric[]
clean_text = clean_text.replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,)
text += clean_text
()
lyric_cut = jieba.cut(text)
lyric_str = .join(lyric_cut)
word_frequency = (lyric_str)
img = Image.()
img_array = np.array(img)
wc = WordCloud(
background_color=,
mask=img_array,
font_path=)
wc.generate_from_text(lyric_str)
()
sql = .(word_rate=word_frequency)
cur.execute(sql)
conn.commit()
cur.close()
conn.close()
()
fig = plt.figure()
plt.imshow(wc)
plt.axis()
plt.savefig(+(word_frequency)+, dpi=)
()
img_url = +(word_frequency)+
render_template(, img_url=img_url, word_frequency=word_frequency)
():
word_frequency =
conn = sqlite3.connect()
cur = conn.cursor()
sql =
table = cur.execute(sql)
row table:
word_frequency = row[]
cur.close()
conn.close()
img_url =
render_template(, img_url=img_url, word_frequency=word_frequency)
():
diy_song_name =
conn = sqlite3.connect()
cur = conn.cursor()
request.method == :
diy_song_name = request.form[]
(request.form)
sql = .(string=diy_song_name)
text =
table = cur.execute(sql)
()
lyric table:
clean_text = lyric[]
(, clean_text)
clean_text = clean_text.replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,) \
.replace(,).replace(,).replace(,).replace(,).replace(,)
(, clean_text)
text += clean_text
()
lyric_cut = jieba.cut(text)
lyric_str = .join(lyric_cut)
word_frequency = (lyric_str)
img = Image.()
img_array = np.array(img)
wc = WordCloud(
background_color=,
mask=img_array,
font_path=)
wc.generate_from_text(lyric_str)
()
sql = .(word_rate=word_frequency)
cur.execute(sql)
conn.commit()
cur.close()
conn.close()
()
fig = plt.figure()
plt.imshow(wc)
plt.axis()
plt.savefig(+ diy_song_name +, dpi=)
()
img_url = + diy_song_name +
render_template(, img_url=img_url, word_frequency=word_frequency,diy_song_name=diy_song_name)
():
render_template()
():
render_template()
__name__ == :
app.run()

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online