ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Python数据可视化实战:网易云音乐歌单分析系统

2026/8/31 13:42:05 拓冰建站 浏览量
Python数据可视化实战:网易云音乐歌单分析系统 简介本资源是一份面向高校计算机与数据科学初学者的Python数据分析实践项目聚焦网易云音乐歌单数据的采集、清洗、统计与可视化全流程解决课程作业中缺乏真实场景练手的问题。压缩包共39个文件含12个核心Python源码实现requests爬取、pandas数据处理、matplotlib/squarify图表绘制、jiebawordcloud词云生成等、3个CSV原始与中间数据集、7张PNG可视化结果图、2份Markdown说明文档及1份PDF结课报告总大小10.53MB结构清晰模块分工明确。已有3340人学习下载适合Python语法入门后希望衔接实战的数据分析新手。读者可直接运行完整分析流程获得评论/收藏/播放量分布图、歌单热度热力图、歌词关键词词云及可落地的歌单优化建议同时掌握bs4网页解析、中文分词、词频统计、多子图布局等关键技能点。 看到这个题目我第一反应是又是一个典型的Python数据分析方向的大学生课程作业。这类项目的核心难点不在代码本身而在于整个分析思路能不能串起来——数据从哪来、怎么清洗、用什么维度分析、最终怎么用图表讲明白一个故事。基于Python数据可视化的网易云音乐歌单分析系统表面上是写一段爬虫加几张图表实际上考察的是你能否完成一条完整的数据分析链路。这个选题本身很有价值歌单数据的结构化程度高、字段丰富适合做多维度的统计与可视化既能满足课程作业的要求也可以作为简历上拿得出手的个人项目。这篇博文会从需求拆解、技术选型、数据获取、数据清洗、可视化实现到常见问题排查把整个项目的完整思路和执行细节都过一遍给正在做类似选题的同学一个可以直接复现的参考。我见过太多同学在一开始就卡在“数据从哪来”这个问题上有些人去研究网易云的加密参数有些人去接第三方接口最后折腾两周还没进入真正的分析环节。实际上课设级别的项目根本不需要把精力耗在反爬对抗上关键在于你有没有一个清晰的分析目标以及能不能用合适的图表把结论呈现出来。下面我就按项目推进的先后顺序把每一部分的思路和操作细节都拆开讲。1. 项目概述与整体设计思路1.1 这个项目到底在解决什么问题先说一个很多人忽略的点老师布置“数据分析”类作业想看的不是你会不会写爬虫而是你有没有建立一套从数据到结论的思考框架。网易云音乐歌单分析系统这个题目本质上是让你回答几个问题什么类型的歌单最容易获得高播放量歌单的收藏数和播放量之间有没有关联哪些标签是热门标签歌单的歌曲数量和热度是否存在关系这些问题拆开来看每一个都是一张图表的分析维度。所以我在动手之前先列了一个分析目标清单歌单播放量的分布情况分析头部效应是否明显不同语种、风格、场景标签的歌单数量占比播放量与收藏量、评论量之间的相关性歌单包含歌曲数量对热度的影响热门歌单创建者的数据特征把这几条列清楚后面的数据采集字段就跟着确定了不需要额外抓一堆用不上的字段。这也是做项目前必须想明白的一件事先有分析目标再去定数据字段而不是把数据抓下来再想能分析什么。1.2 技术选型为什么是Python pandas matplotlib这个组合已经是课设标配了但很多同学只是“随大流”选型不知道每个组件解决什么问题。我的理解是这样的Python作为胶水语言生态完善requests做数据采集、pandas做数据处理、matplotlib做图表输出整个链路一套语言跑通不需要在不同工具之间切换。对比一下其他方案如果你用Excel数据处理方便但无法自动化用Java数据处理库太啰嗦图表基本要外接组件用R语言数据分析和可视化确实强但语法对新手不够友好而且调试环境配置比Python麻烦。Python最大的优势就是用最少的代码完成最多的工作几分钟就能出一张图迭代效率高。具体到库的选型上pandas负责数据清洗和聚合统计它内置的DataFrame结构非常适合处理表格型数据。matplotlib是最基础的绘图库seaborn是在它之上封装的高层接口图表美观度更高适合画统计图。我再加一个建议如果课程允许可以考虑用plotly画交互式图表鼠标悬停就能看到数据细节展示环节会很加分。不过底层的matplotlib最好还是熟练掌握因为很多学校答辩环境不联网plotly的离线渲染在某些环境下会有兼容性问题。1.3 分析对象选择为什么是歌单而不是歌曲或用户有些同学看到题目是“网易云音乐”第一反应是去爬歌曲评论或者用户信息。我的建议是不要做选择歌单作为分析对象是性价比最高的方案。原因有三点。第一歌单本身就是网易云音乐的核心组织单位用户围绕歌单产生了大量行为数据比如收藏、评论、分享这些数据信息密度高非常适合统计分析。第二歌曲数据和用户数据要么涉及大量反爬限制要么字段太稀疏比如用户隐私字段敏感、评论数据清洗复杂课设时间根本不够用。第三歌单数据天然自带分类标签这个属性能直接做多维度的分组统计省去大量特征工程的工作。我见过有人选了热门歌曲排行榜做分析结果数据量太大、字段复杂光清洗就花了三周最后图表质量反而一般。歌单数据单条信息量大、量级适中几十条到几百条样本就能做出很漂亮的分布图这才是课设的合理体量。2. 数据获取与数据清洗实战2.1 数据源与合规性说明前面说了不要死磕反爬实际操作中有三种方案可以拿到数据。第一种是手工整理小样本数据适合时间紧、只需要完成作业功能的同学。打开网易云音乐的歌单广场按播放量排序手动记录歌单名称、播放量、收藏数、歌曲数、标签等字段录入Excel或CSV文件录入50到100条就能支撑课程作业的图表需求。这个方案看起来原始但胜在稳定可控而且数据质量高不会有字段缺失的问题。第二种是使用网易云音乐公开接口。注意这里说的是公开接口不是破解加密参数的私密接口。通过公开接口获取数据仍然需要合理控制请求频率只做个人学习用途。我在实操部分会给出具体方案。第三种是使用公开数据集。GitHub和Kaggle上有很多现成的网易云音乐歌单数据集下载下来直接做分析。这个方案最省事但缺点是数据集可能比较旧而且字段不知道是否完整。用公开数据集之前一定要先做数据探索看看字段范围是否满足你的分析目标。这里务必强调合规性数据分析课设只能使用公开数据或自己整理的数据不能绕过平台的风控机制大规模抓取数据。如果项目报告里需要写数据来源建议如实写“使用公开数据集少量手工补充”这也是评分老师更愿意看到的诚实做法。2.2 数据字段设计与采集模板无论采用哪种数据获取方式字段设计决定了后面能分析什么。我推荐的歌单数据字段如下字段名类型说明playlist_idint歌单ID去重用namestr歌单名称creatorstr创建者昵称play_countint播放量track_countint歌曲数量sub_countint收藏数comment_countint评论数tagsstr标签多个标签用逗号分隔create_timestr创建时间如果你用的是手工整理方案按这个表头建一个CSV文件就行。注意几个易错点播放量在网页上显示为“1234万”这种格式录入时要换算成纯数字tags字段建议保持原始字符串因为后面要拆分成多个维度做统计create_time最好统一成“YYYY-MM-DD”格式方便后续做时间维度分析。2.3 用Pandas完成数据清洗数据清洗是决定分析质量的关键一步。很多报表看起来不对劲根源就是数据没洗干净。先看一个典型的数据加载代码import pandas as pd df pd.read_csv(playlist_data.csv, encodingutf-8) print(df.info()) print(df.head())数据加载之后第一件事是检查info()输出的每一列字段类型和缺失值情况。如果你的播放量被读成了对象类型object说明CSV里有非数字字符比如“1.2万”这种格式需要先做字符串替换def convert_play_count(value): if isinstance(value, str): if 万 in value: return float(value.replace(万, )) * 10000 else: return float(value) return value df[play_count] df[play_count].apply(convert_play_count)接下来处理缺失值和重复值# 查看缺失值 print(df.isnull().sum()) # 处理缺失值播放量、收藏数为空的直接删除该行 df df.dropna(subset[play_count, sub_count]) # 处理重复值 df df.drop_duplicates(subset[playlist_id]) # 统一数值类型 df[play_count] df[play_count].astype(int) df[sub_count] df[sub_count].astype(int) df[track_count] df[track_count].astype(int)这里有一个容易踩的坑astype(int)转换时如果某条数据里有小数或者空值会直接报错。所以先dropna再转换是顺序不能乱的。另外如果要分析标签维度需要把tags字段拆开# 标签拆分成列表 df[tag_list] df[tags].str.split(,)然后可以使用explode()把标签行展开每行一个标签方便后续分组统计tags_df df.explode(tag_list) tag_counts tags_df[tag_list].str.strip().value_counts()数据清洗做完之后可以顺手统计一下完成率比如清洗前和清洗后的数据行数对比这个数据写到课设报告里也能体现你的工作量。3. 数据可视化从需求到图表的完整链路3.1 可视化库选型matplotlib、seaborn、plotly怎么取舍可视化库选型直接影响出图效率和最终效果。我的习惯是分场景选库。matplotlib是最底层的框架API功能完整、可定制性强但默认样式偏学术代码量稍大。seaborn基于matplotlib封装默认配色更好看画统计图非常方便比如分布图、回归图、热力图一行代码就能出图。plotly则是交互式图表的代表网页端展示效果好适合答辩演示。对于这个歌单分析项目我的建议是matplotlib seaborn组合搞定80%的图表如果你有余力再用plotly做一两个交互图表作为亮点。没必要从头到尾只用plotly因为有些环境下渲染依赖较多导出报告用静态图片反而不方便。3.2 图表规划逻辑你的分析报告要讲什么故事很多同学画图表是“想到一张画一张”最后图虽然多但逻辑零散。一个更好的做法是像写文章一样先规划图表的叙事线。我的分析报告按这个顺序组织图表第一部分数据概览展示歌单播放量整体分布情况第二部分歌单标签结构分析看看热门标签有哪些第三部分歌单热度因素分析探索播放量与收藏数、歌曲数之间的关系第四部分创作者生态分析看看高产创作者和热门歌单的特征每张图对应一个章节每个章节解决一个问题。这样老师看报告时能很清晰地看到你的分析主线评分自然更高。3.3 核心图表实现与解读第一张图播放量Top10歌单的横向柱状图import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False top10 df.nlargest(10, play_count) plt.figure(figsize(10, 6)) plt.barh(top10[name].str[:15], top10[play_count], color#2d8cf0) plt.xlabel(播放量) plt.ylabel(歌单名称) plt.title(播放量Top10歌单) plt.gca().invert_yaxis() plt.tight_layout() plt.savefig(top10_playlist.png, dpi150) plt.show()注意我用了plt.rcParams设置中文字体如果系统里没有SimHei会乱码后面第5章专门说这个问题。横向柱状图适合展示排名类数据因为歌单名称比较长横向显示更清晰。barh配合invert_yaxis()让排名第一的在最上面符合阅读习惯。第二张图热门标签的Top15柱状图tag_counts.head(15).plot(kindbarh, figsize(10, 6), color#19be6b) plt.xlabel(歌单数量) plt.ylabel(标签) plt.title(热门歌单标签Top15) plt.gca().invert_yaxis() plt.tight_layout() plt.savefig(top_tags.png, dpi150) plt.show()第三张图播放量与收藏数的散点图。这个图能直观验证一个假设播放量和收藏数是否存在正相关关系。因为数据范围大我用了log变换让点的分布更均匀import numpy as np import seaborn as sns plt.figure(figsize(8, 6)) sns.scatterplot(xnp.log1p(df[play_count]), ynp.log1p(df[sub_count]), alpha0.6) plt.xlabel(播放量(log)) plt.ylabel(收藏数(log)) plt.title(播放量与收藏数关系) plt.tight_layout() plt.savefig(play_vs_sub.png, dpi150) plt.show()用np.log1p而不是np.log是因为有些歌单播放量为0log(0)会报无穷大。log1p是log(x1)既保留0值数据又压缩了大数值的分布范围。第四张图可以用热力图看多个变量的相关性numeric_cols df[[play_count, track_count, sub_count, comment_count]] corr numeric_cols.corr() plt.figure(figsize(8, 6)) sns.heatmap(corr, annotTrue, cmapcoolwarm, fmt.2f) plt.title(歌单数字字段相关性矩阵) plt.tight_layout() plt.savefig(corr_heatmap.png, dpi150) plt.show()这张热力图放报告里会显得分析思路很完整。从相关性矩阵能看到收藏和评论高度正相关、播放和收藏正相关而歌曲数和播放量相关性较弱这说明歌单热度主要由内容质量和标签推荐决定而不是堆量。3.4 让图表更容易拿高分的小技巧图表本身的美观度在课设评分里占很大比重。我总结几个提升图表质感的小细节。第一统一配色。不要每张图都用默认颜色指定一套主题色会让报告看起来更专业。我常用的是蓝绿色系比如主色#2d8cf0、辅助色#19be6b。第二标注数据标签。柱状图顶部加柱子的数值能让读者一眼看出具体数据。第三保存高清图。plt.savefig里设置dpi150以上图片插入Word或WPS里才不会模糊。如果是报告提交建议把dpi设到200。第四不要出现裸图。每张图配上注释文字说明图的含义和结论。这个在课设报告里尤其重要直接体现你的分析能力。4. 实操过程与核心代码实现4.1 项目目录结构与依赖安装一个清晰的项目结构能让你自己也好维护。我建议用下面的目录netease_playlist_analysis/ ├── data/ │ └── playlist_data.csv ├── output/ │ ├── top10_playlist.png │ ├── top_tags.png │ └── play_vs_sub.png ├── main.py ├── analysis.ipynb └── requirements.txt依赖清单放在requirements.txt里pandas1.5.3 matplotlib3.7.1 seaborn0.12.2 numpy1.24.3安装命令pip install -r requirements.txt如果你是pip安装慢可以加镜像源比如清华源pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple4.2 数据加载与清洗完整代码我把数据清洗部分写成一个函数后面分析时直接调用逻辑清晰也方便复用import pandas as pd def load_and_clean_data(filepath): # 加载数据 df pd.read_csv(filepath, encodingutf-8) # 删除完全空行 df df.dropna(howall) # 播放量转换处理万格式 def convert_count(value): if isinstance(value, str): value value.strip() if value.endswith(万): return float(value[:-1]) * 10000 if value or value -: return None return float(value) df[play_count] df[play_count].apply(convert_count) df[sub_count] df[sub_count].apply(convert_count) df[comment_count] df[comment_count].apply(convert_count) # 删除关键字段为空的行 df df.dropna(subset[play_count, sub_count]) # 去重 df df.drop_duplicates(subset[playlist_id], keepfirst) # 数值类型转换 df[play_count] df[play_count].astype(int) df[sub_count] df[sub_count].astype(int) df[track_count] pd.to_numeric(df[track_count], errorscoerce).fillna(0).astype(int) df[comment_count] df[comment_count].astype(int) # 拆分标签 df[tag_list] df[tags].str.split(,) return df df load_and_clean_data(data/playlist_data.csv) print(f清洗后数据量: {len(df)})4.3 可视化代码完整示例在实际运行中我建议做成脚本一次输出所有图表这样不会遗漏也方便批量更新import matplotlib.pyplot as plt import seaborn as sns import numpy as np plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # 图表1播放量Top10 top10 df.nlargest(10, play_count) plt.figure(figsize(10, 6)) bars plt.barh(top10[name].str[:15], top10[play_count], color#2d8cf0) for bar in bars: width bar.get_width() plt.text(width * 1.02, bar.get_y() bar.get_height() / 2, f{int(width):,}, vacenter, fontsize9) plt.xlabel(播放量) plt.ylabel(歌单名称) plt.title(播放量Top10歌单) plt.gca().invert_yaxis() plt.tight_layout() plt.savefig(output/top10_playlist.png, dpi150, bbox_inchestight) plt.show() # 图表2热门标签Top15 tags_df df.explode(tag_list) tags_df[tag_list] tags_df[tag_list].str.strip() tag_counts tags_df[tag_list].value_counts().head(15) plt.figure(figsize(10, 6)) top_tags tag_counts.sort_values() top_tags.plot(kindbarh, color#19be6b) for i, v in enumerate(top_tags.values): plt.text(v 0.5, i, str(v), vacenter, fontsize9) plt.xlabel(歌单数量) plt.ylabel(标签) plt.title(热门歌单标签Top15) plt.tight_layout() plt.savefig(output/top_tags.png, dpi150, bbox_inchestight) plt.show() # 图表3播放量与收藏数散点图 plt.figure(figsize(8, 6)) sns.scatterplot(xnp.log1p(df[play_count]), ynp.log1p(df[sub_count]), alpha0.6, s30, color#2d8cf0) sns.regplot(xnp.log1p(df[play_count]), ynp.log1p(df[sub_count]), scatterFalse, colorred, line_kws{linestyle: --}) plt.xlabel(播放量(log)) plt.ylabel(收藏数(log)) plt.title(播放量与收藏数关系) plt.tight_layout() plt.savefig(output/play_vs_sub.png, dpi150, bbox_inchestight) plt.show() # 图表4相关性热力图 numeric_cols df[[play_count, track_count, sub_count, comment_count]].corr() plt.figure(figsize(8, 6)) sns.heatmap(numeric_cols, annotTrue, cmapcoolwarm, fmt.2f, squareTrue) plt.title(歌单数字字段相关性矩阵) plt.tight_layout() plt.savefig(output/corr_heatmap.png, dpi150, bbox_inchestight) plt.show()4.4 运行效果与结果解读运行上面代码后output目录下会有4张PNG图片。我把每张图的分析结论写下来供报告参考。播放量Top10歌单显示头部歌单播放量动辄千万级长尾效应很明显头部歌单以“华语”“流行”“治愈”类为主。热门标签Top15中“华语”“流行”“治愈”“深夜”“学习”是出现频率最高的标签这说明用户的听歌场景偏情绪陪伴类。播放量与收藏数的散点图呈明显的线性正相关趋势说明播放量越高的歌单越容易被收藏。相关性热力图进一步验证评论数和收藏数相关系数最高而歌曲数和其他字段的相关性很弱。5. 常见问题与排查技巧实录5.1 环境相关的坑最常见的报错是ModuleNotFoundError: No module named pandas原因是没有激活对应的虚拟环境或者装在了另一个Python版本下。排查三步先看当前用的是哪个Python解释器再确认pip对应的版本最后用pip list检查有没有装成功。另一个高频问题是pip安装慢到超时可以临时指定镜像源pip install pandas matplotlib seaborn或者用国内镜像pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple5.2 数据处理相关的坑Pandas读取CSV时最常见的错误是UTF-8编码问题特别是用WPS或记事本保存的CSV默认是GBK编码。解决办法是read_csv时显式指定编码df pd.read_csv(playlist_data.csv, encodinggbk)如果懒得试可以直接用encodinggbk然后看是否报错再去试。另一个问题是数值列中混入空白字符导致astype(int)失败。处理办法是先做strip再to_numeric加errorscoerce把无法解析的变成NaN。列名大小写不一致也是一个容易忽略的问题建议在read_csv之后统一列名风格df.columns [col.strip().lower() for col in df.columns]5.3 中文字体与显示相关的坑这一节我单独拎出来说是因为几乎每个做中文可视化的同学都会碰到中文乱码问题。最典型的现象是图上所有中文都变成一个个小方框。原因在于matplotlib默认字体不包含中文字符需要手动指定中文字体。Windows系统推荐用SimHei黑体macOS可以用Arial Unicode MS或PingFang SCLinux需要安装中文字体包再指定对应字体名。我的建议是前三行统一设置plt.rcParams[font.sans-serif] [SimHei, Arial Unicode MS, PingFang SC] plt.rcParams[axes.unicode_minus] False第二行的作用是让负号正常显示不然坐标轴的负号也会变成方块。如果换了字体名称还是乱码可以查看系统里有哪些可用中文字体import matplotlib.font_manager as fm fonts [f.name for f in fm.fontManager.ttflist if Hei in f.name or Song in f.name or PingFang in f.name] print(set(fonts))5.4 排查技巧速查表问题现象可能原因解决方案pandas导入失败环境变量或pip版本不对检查解释器用python -m pip installCSV中文乱码文件编码不是UTF-8用encodinggbk读入matplotlib中文变方块未设置中文字体设置rcParams字体柱状图数值重叠标签太长限制字符串长度name.str[:15]热力图不显示数值缺少annot参数加annotTrue图保存后空白未调用savefig或dpi太低设置dpi150, bbox_inchestight数值转换报错字符串含特殊字符stripto_numeric(errorscoerce)两张图互相覆盖未新建figure每张图加plt.figure()5.5 一个容易被忽视的细节在报告中放“图表解读”这一点对拿高分特别重要。很多同学的课设报告里图很多但每张图下面只有一句“从图中可以看出……”没有具体的数据支撑和分析深度。我的建议是每张图配三段式解读这张图展示了什么、数据上有什么突出特征、这个特征说明了什么。比如播放量Top10歌单的图可以这样解读从数据分布来看第一名歌单播放量超过1亿而第十名只有5000万左右头部歌单之间存在显著的播放量差距。结合Top15标签的统计可以发现头部歌单集中分布在“华语”“流行”“治愈”等标签下说明平台热门歌单的品类比较集中。这样的解读既有数据又有结论老师一眼就能看出你的分析能力。写在最后从课设到作品集的小建议我做这个项目最大的体会是课设级别的数据分析项目不在于用了多少花哨的技术而在于你把一条简单的数据链路走得多完整。很多同学在爬虫阶段就耗尽精力最后分析部分草草了事反而得不偿失。如果时间有限手工整理100条高质量的歌单数据把清洗、分析和可视化做扎实效果远好于爬了1万条脏数据然后东拼西凑。最后再分享一个小技巧做完项目之后把代码里关键的分析结论整理成几行文字粘贴到GitHub仓库的README里再配上三张最有说服力的图表。这样写课程作业也好、以后找实习也罢都可以直接拿这个项目来展示你的数据分析思路。如果后续还有时间可以把plotly交互式图表引进来或者增加一个简单的词云图分析歌单名称的高频词这两个方向都能让项目在班级里脱颖而出。本文还有配套的精品资源点击获取