尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

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

发布时间:2026/9/25 4:35:48

资讯中心
01
ARTICLE

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

Python数据分析实战:网易云音乐歌单可视化系统完整实现
简介一份基于Python数据可视化的网易云音乐歌单分析系统源码与文档说明项目资源面向正在学习Python数据分析、需要完成课程设计或期末大作业的高校学生特别适合用作高分大作业参考。项目完整实现了从网易云音乐歌单数据爬取、数据清洗到可视化分析的全流程利用numpy、pandas、matplotlib、requests、jieba、wordcloud等第三方库产出评论、收藏、播放、贡献分布数量图及词云并给出歌单优化建议。资源共38个文件包括12个Python源码文件、11个编译缓存pyc文件、7张结果图片、3个CSV数据文件、1个词云字体文件、1个PDF手册、1个DOCX说明文档等压缩包约12.23MB文件类型覆盖代码、数据、图表与文档目录结构清晰便于对照学习。目前已有785人学习浏览适合需要参考完整数据分析项目流程、练习爬虫与可视化技巧的读者。通过阅读源码和配套文档可掌握数据获取、清洗、分析、可视化及报告撰写的完整思路还能了解中文分词、词云生成、矩形树图绘制等具体实现技巧。1. 期末大作业最常见的翻车点图表有了结论没了“Python 数据分析初探项目 基于 Python 数据可视化的网易云音乐歌单分析系统”这个标题背后其实是一个很典型的场景你要在本学期末交出一份能拿高分的数据分析大作业数据源选的是网易云音乐歌单手段是 Python 数据分析与可视化交付物是源码加文档说明。很多人的做法是下载一份歌单数据画几张柱状图折线图然后凑出一篇报告最后被老师问一句“你的图表说明什么”就答不上来。这个系统的价值不在于图表有多花哨而在于把“从数据到结论”这条路走通歌单的播放量、收藏量、歌曲数量、标签分布这些字段经过清洗、聚合、可视化之后能回答“什么样的歌单更容易被收藏”“标签和播放量有没有关系”这类具体问题。适合期末大作业、课程设计也适合刚学完 Pandas 和 Matplotlib 想找个完整练手项目的人。本文按我实际做过的方案来拆解从数据获取讲到图表输出最后把遇过的坑都列出来。2. 先把数据和字段理顺歌单分析系统的地基2.1 数据从哪来接口抓取还是本地文件做歌单分析第一步不是写可视化代码而是先把数据拿到手。常见做法有两种一种是直接请求网易云的歌单接口拿 JSON另一种是用现成的导出工具或数据集文件。对期末大作业来说我建议优先走接口抓取因为能体现爬虫能力而且数据是自己抓的答辩时经得起问。接口抓取的思路是歌单列表页的背后有一个分页接口返回的 JSON 里包含歌单 ID、名称、播放量、收藏数、歌曲数、创建者等信息。请求时带一个 UA 伪装成浏览器一般就能拿到数据。这里的关键参数是分页的 offset 和 limit比如一次取 50 个歌单翻页就改 offset。要注意的是接口字段名在不同时期会变你抓回来后先打印一条记录看结构再决定字段映射。我自己更常用的方式是先抓一次落盘成 JSON后面的步骤全部基于本地文件做避免频繁请求被限流。这样清洗、可视化、写报告可以分开跑不会因为网络波动导致整个流程挂掉。数据量上我一般抓 1000 到 2000 个歌单就够分析了再多对结论帮助不大反而可能被风控盯上。import json import time import requests headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } playlist_data [] for offset in range(0, 500, 50): # 10页每页50条共500条 url https://xxx.example.com/api/playlist # 换成实际可用的歌单接口 params {offset: offset, limit: 50} resp requests.get(url, headersheaders, paramsparams, timeout10) if resp.status_code ! 200: print(foffset{offset} 请求失败状态码 {resp.status_code}) break items resp.json().get(playlists, []) if not items: break playlist_data.extend(items) time.sleep(1) # 控制请求频率避免被限流 with open(playlists_raw.json, w, encodingutf-8) as f: json.dump(playlist_data, f, ensure_asciiFalse, indent2) print(f抓取完成共 {len(playlist_data)} 条歌单)这段代码有两点值得说明。第一是sleep(1)每页请求间隔一秒这是爬虫的基础素养也是期末答辩时老师会问到的细节第二是状态码判断和空列表判断接口一旦返回异常就停不会让程序闷头跑下去。offset单位是页内游标每页 50 条500 条数据意味着 offset 取 0 到 450 之间每次加 50。如果你只需要做分析演示200 条也够重点是后面能讲出故事。2.2 清洗脚本把脏数据变成能分析的 DataFrame抓下来的 JSON 里播放量可能是字符串“123.4万”收藏数可能缺失标签可能是个列表歌曲数可能是字符串。这些不处理后面画图全是坑。清洗步骤一般是从 JSON 里抽出关键字段构建 DataFrame把“万”转成数字缺失值统一填充或丢弃重复歌单去重最后存成 CSV。import pandas as pd with open(playlists_raw.json, r, encodingutf-8) as f: data json.load(f) rows [] for item in data: rows.append({ playlist_id: item.get(id), name: item.get(name), play_count: item.get(play_count, 0), book_count: item.get(book_count, 0), track_count: item.get(track_count, 0), tags: item.get(tags, []), creator: item.get(creator, {}).get(nickname, ), create_time: item.get(create_time, 0), }) df pd.DataFrame(rows) df df.dropna(subset[playlist_id, name]) df df.drop_duplicates(subset[playlist_id]) def convert_wan(value): if isinstance(value, str): if 万 in value: return float(value.replace(万, )) * 10000 return float(value) return float(value) df[play_count] df[play_count].apply(convert_wan) df[book_count] df[book_count].apply(convert_wan) df.loc[df[track_count].isna(), track_count] 0 df[track_count] df[track_count].astype(int) df.to_csv(playlists_clean.csv, indexFalse, encodingutf-8-sig) print(df[[name, play_count, book_count, track_count]].head())这里四个操作要重点理解。dropna只针对主键字段歌单名和 ID 为空的行没有分析价值直接丢drop_duplicates用歌单 ID 去重因为分页抓取时可能遇到同一个歌单出现在不同页。convert_wan是核心转换函数把“123.4万”拆成数字再乘 10000这里必须写成函数而不是循环体内重复代码因为 Pandas 的apply比遍历快一个量级。最后存 CSV 时用utf-8-sig编码这是 Windows 下 Excel 打开不乱码的关键参数很多人在这一步翻车。清洗完先别急着画图先跑一句df.describe()看分布。我一般会检查 play_count 的最大值、中位数、是否出现极端值这决定后面可视化用线性的还是对数的坐标轴。3. 可视化落地让图表替你说话3.1 图表选型先定结论再定图数据可视化最忌讳的是“先画一堆图再说”。正确的操作是先问自己老师看完报告希望你记住什么结论对歌单分析系统来说三个问题值得回答播放量分布是否极端、收藏量和播放量是否相关、哪些标签的歌单更容易受欢迎。三个问题对应三张图直方图、散点图、标签条形图。选型逻辑也很简单分布看直方图相关性看散点图排名看条形图。不要一上来就用 echarts 画炫酷的动态图默认的 Matplotlib 足够拿高分关键是你能不能解释清楚每个轴的含义。如果你的报告需要交互式图表用 pyecharts 导出 HTML 是加分项但那是后期的事先把静态图做扎实。3.2 三张核心图分布、相关与排名这三张图的代码可以放在一个脚本里方便统一管理和复现。播放量分布图重点看是否长尾收藏和播放的散点图看有没有线性关系标签的条形图把集中出现的标签列出来。图表标题、轴标签、网格线是评分老师最注意的细节。import matplotlib.pyplot as plt import pandas as pd import numpy as np df pd.read_csv(playlists_clean.csv, encodingutf-8-sig) # 图一播放量分布直方图 plt.rcParams[font.sans-serif] [Microsoft YaHei] plt.rcParams[axes.unicode_minus] False fig, axes plt.subplots(1, 3, figsize(16, 5)) axes[0].hist(df[play_count], bins50, color#2d7dd2, edgecolorwhite) axes[0].set_title(歌单播放量分布) axes[0].set_xlabel(播放量) axes[0].set_ylabel(歌单数量) axes[0].grid(alpha0.3) # 图二收藏量与播放量的散点图 axes[1].scatter(df[play_count], df[book_count], alpha0.4, s10, c#d45e5e) axes[1].set_title(收藏量 vs 播放量) axes[1].set_xlabel(播放量) axes[1].set_ylabel(收藏量) axes[1].set_xscale(log) axes[1].set_yscale(log) axes[1].grid(alpha0.3) # 图三出现频次最高的前15个标签 from collections import Counter tag_counter Counter() for tags in df[tags].dropna(): for tag in tags: tag_counter[tag] 1 top_tags tag_counter.most_common(15) tag_names [t[0] for t in top_tags][::-1] tag_counts [t[1] for t in top_tags][::-1] axes[2].barh(tag_names, tag_counts, color#3a923a) axes[2].set_title(歌单标签频次 Top15) axes[2].set_xlabel(歌单数量) axes[2].grid(axisx, alpha0.3) plt.tight_layout() plt.savefig(playlist_analysis.png, dpi150, bbox_inchestight) plt.show()代码里有两个参数值得细说。plt.rcParams那两行是中文显示的关键font.sans-serif设置中文字体axes.unicode_minus解决负号显示成方块的问题不同操作系统字体名不同Windows 是 “Microsoft YaHei”macOS 用 “PingFang SC”Linux 可能要用 “WenQuanYi Zen Hei”。set_xscale(log)是第二处关键参数歌单播放量跨好几个数量级线性刻度会把小播放量的数据堆在原点对数刻度才能看出分布形态。散点图的alpha0.4处理大量点重叠时的透明度问题。3.3 中文显示与导出答辩现场最容易翻车的两件事中文乱码是期末大作业里出现频率最高的 bug没有之一。你本地跑得好好的到答辩电脑上图表全变方块这不是玄学是目标机器没有你指定的中文字体。解决办法有两个一是在代码里加一个字体探测函数二是保存成图片而不是依赖交互窗口。我倾向于后者savefig时指定dpi150以上图片直接插入报告答辩就用这张图不用现场重新跑。还有一个容易忽略的点图表文件命名不要用“图1.png”这种用playlist_playcount_dist.png这种带语义的名字后期写文档说明时你才知道哪张图对应哪段分析。另外bbox_inchestight这个参数要养成习惯不然图表标题会被裁掉这是 Matplotlib 新手最容易忽视的。def setup_chinese_font(): import matplotlib.font_manager as fm candidates [Microsoft YaHei, SimHei, PingFang SC, WenQuanYi Zen Hei] installed {f.name for f in fm.fontManager.ttflist} for name in candidates: if name in installed: plt.rcParams[font.sans-serif] [name] return plt.rcParams[font.sans-serif] [candidates[0]] setup_chinese_font()这个函数的核心逻辑是候选字体按系统优先级排列逐个检查是否存在于当前机器存在就用不存在就跳过。它的价值在于你的代码拷贝到任何一台电脑上都能自适应字体不用改参数。这是我从“本地能跑、换机就挂”的教训里提炼出来的。4. 避坑网易云歌单分析里的 5 个典型问题4.1 播放量带“万”字排序和分析全错现象画条形图时播放量 12000 的歌单排在 3.2万 前面因为字符串排序时数字字面量小的排在前面带“万”的根本不成数值。原因网易云接口返回的播放量字段在部分场景下是格式化后的字符串比如“3.2万”没有做转换直接进 DataFramePandas 按 object 类型处理排序和运算全部用字符串逻辑。解决在清洗阶段统一走函数转换发现字符串里有“万”就替换成数字乘 10000。注意处理两种边界纯数字字符串和带“亿”的极端值。转换完用df[play_count].dtype确认是 float 或 int再进入可视化和统计环节。4.2 CSV 用 Excel 打开乱码现象df.to_csv(playlists_clean.csv)存完用 Excel 打开全是乱码但用记事本打开正常。原因Pandas 默认编码是 UTF-8Excel 对 UTF-8 无 BOM 的兼容有问题。解决写入时指定encodingutf-8-sig这是带 BOM 的 UTF-8Excel 能正确识别。同理如果从 Excel 存 CSV 再读回 Pandas要用encodinggbk或encodingutf-8-sig试读大概率是两者之一。4.3 词云图上全是“的”“了”“音乐”现象对歌单名称做词云高频词全是无意义的虚词和“音乐”“歌单”这种通用词看不出特征。原因没做分词过滤或者说停用词表里没有针对网易云场景的专属词。解决用 jieba 分词加载一个停用词表至少要把“音乐”“歌单”“歌曲”“经典”“精选”这种业务里必然高频但没有区分度的词停掉。词云的 font_path 参数必须指定一个中文字体文件路径否则中文全变方块和图表中文乱码是一个根源。4.4 标签字段是数组直接计数会报错现象df[tags].value_counts()报TypeError: unhashable type: list或者画图时标签全部显示不出。原因歌单的 tags 是一个列表比如[华语, 流行]Pandas 没法对列表做 value_counts。解决用collections.Counter在外层遍历把每个列表的元素拆开放进 Counter。这一步要在清洗阶段完成而不是放在绘图脚本里否则你每次画图都要重新拆一次。4.5 接口请求频率过高被限流现象程序跑到第 3 页突然连续报 403或者返回的数据结构变了字段名对不上。原因请求频率太高服务器的风控逻辑把 IP 临时限制或者接口升级导致字段变更。解决time.sleep(1)只是最低限度的礼貌更稳的做法是每次请求前随机 sleep 0.5 到 2 秒并且对状态码 403 做重试退避。抓到一半挂了也别慌把已经抓到的落盘调整参数后继续抓不要从头再来。字段变了就直接打印返回的 JSON 前 200 字符看新的字段名这是排查最快的方式。5. 让作业变成能复用的东西脚本参数化与结论验证期末大作业交付的“源码 文档说明”很多人只做到了“能跑”没做到“能被别人跑起来”。我最后说两个习惯一个是把脚本从“改代码改数据”变成“改参数跑数据”另一个是每张图都要能说出结论。脚本参数化的做法是引入argparse把输入文件、输出路径、图表类型作为命令行参数传进去。比如你写了三张图就支持--chart-type hist、scatter、barh分别运行这样别人拿到你的源码不用看懂代码细节也能复现你的图表。import argparse parser argparse.ArgumentParser(description网易云歌单分析可视化) parser.add_argument(--input, defaultplaylists_clean.csv, help清洗后的CSV路径) parser.add_argument(--chart-type, choices[hist, scatter, barh], defaulthist, help图表类型) args parser.parse_args() df pd.read_csv(args.input, encodingutf-8-sig) if args.chart_type hist: # 播放量分布图逻辑 pass elif args.chart_type scatter: # 收藏与播放散点图逻辑 pass elif args.chart_type barh: # 标签排名逻辑 pass文档说明也是一样README 里只写三件事数据怎么来的、清洗脚本怎么跑、三张图各自回答什么问题。不要写大段的环境安装教程pip install -r requirements.txt一行带过就行。数据字典可以单独放一个 CSV 示例每个字段一行注释比写长篇说明文档有效得多。结论验证这步我的检查习惯是每张图输出后强制自己用一句话说出“这张图证明了什么”。比如直方图显示播放量集中在 10 万以下长尾延伸到千万级说明歌单的马太效应很强散点图显示收藏量随播放量增长呈亚线性说明高播放歌单的收藏转化率反而低。说得出来的图才留在报告里说不出来的图删掉这是我从多次答辩里总结出来的纪律。这套系统的天花板不在可视化效果在于你能不能把数据分析的“分析”二字做实提出一个问题用数据回答它用图表佐证它。以上是我做这类项目一路走下来的经验和习惯希望能帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。