简介:用Django开发的网易云音乐数据分析平台,内置Scrapy爬虫自动抓取歌曲、歌手、评论等公开数据,支持存入本地MySQL数据库;前端通过动态图表展示播放量、热度排行、用户评论情感分布等核心指标,形成实时更新的数据大屏;系统包含cloudmusic_django主应用、song_reco推荐模块、data_apply分析逻辑、admin后台管理界面,以及清晰的models定义和URL路由;提供README说明文档和设计报告模板,覆盖需求分析、技术选型、数据库ER图、API接口列表与Docker/uWSGI部署流程;预置CSV示例数据和SQL初始化脚本,也兼容自定义爬取结果;Python 3.8环境一键运行,无需额外配置即可启动开发服务器查看效果;适合计算机、软件工程类专业学生做毕业设计或课程实训,教师也可用于教学演示与项目指导。
1. 这不是“做个网页”,而是一套可交付的数据分析闭环系统
你手头拿到的这个项目,名字叫“Django搭建的网易云音乐数据大屏系统”,但千万别被“大屏”两个字带偏了——它本质上是一个端到端的数据产品最小可行原型(MVP):从原始数据采集、结构化存储、业务逻辑处理、可视化呈现,到后台管理与文档交付,五个关键环节全部打通,且每个环节都落在真实开发场景的“痛点击中点”上。我带过十几届毕业设计,见过太多学生卡在“爬不到数据”“存不进数据库”“图表不刷新”“部署就报错”这四个死循环里,最后交出一个只有静态HTML的“假大屏”。而这个项目,是真正跑起来就能看到滚动播放量、实时更新热评词云、后台一键导出歌手TOP50的完整链路。
核心关键词里,“Django”不是装饰词,而是整个系统的骨架和神经中枢;“网易云音乐”在这里不是目标平台,而是公开数据源的典型样本——它的页面结构稳定、反爬策略温和(无验证码、无强JS渲染)、数据维度丰富(歌曲/专辑/歌手/评论/点赞数/发布时间),特别适合作为教学级数据工程的练兵场;“数据大屏”不是炫技的PPT动效,而是基于ECharts + Django模板引擎实现的服务端渲染+前端异步轮询混合方案,既保证首屏加载速度,又支持分钟级数据刷新;“Scrapy爬虫”不是简单写个requests循环,而是完整实现了分布式爬取调度、去重指纹管理、异常重试队列、字段标准化清洗等工业级能力;“可视化分析”则体现在data_apply模块里——它不是把数据扔给图表库就完事,而是封装了热度加权算法(播放量×评论数×时间衰减因子)、情感倾向统计(基于SnowNLP轻量级中文分词+情感词典匹配)、相似歌曲推荐(TF-IDF向量化+余弦相似度计算)等真正能讲出业务故事的逻辑。
这套系统适合谁?如果你是计算机或软工专业的学生,它能让你在两周内完成一个“有数据、有逻辑、有界面、有文档”的硬核毕设;如果你是授课教师,它是一套开箱即用的教学案例包——你可以直接拆解出“Scrapy中间件编写”“Django ORM多表关联查询优化”“ECharts动态数据绑定”三个实验课主题;如果你刚学完Python基础想进阶,它就是你跳过“Hello World”直面真实项目复杂度的第一块跳板。我去年帮三个学生用这个底座改造成“豆瓣电影评分分析系统”,他们只替换了爬虫规则和模型字段,三周就完成了答辩演示。关键在于,它不教你“怎么写代码”,而是示范“怎么让代码解决实际问题”。
2. 系统架构设计:为什么选择Django而非Flask或FastAPI?
2.1 选型背后的现实考量:毕设场景下的“稳”字诀
很多初学者看到“数据大屏”第一反应是选Vue+FastAPI——技术栈新、性能好、社区火。但当你真要带着导师验收、赶答辩 deadline、面对实验室老旧服务器时,就会发现:Django的“重”恰恰是它的护城河。这个项目选择Django,根本原因不是技术先进性,而是它对“教学型项目交付”场景的极致适配。我来拆解几个关键决策点:
首先是开发效率与维护成本的平衡。Django自带Admin后台、ORM、用户认证、URL路由、模板引擎,这些在毕设中都是刚需。比如Admin后台,学生不用花三天写CRUD接口,直接注册model就能获得增删改查界面;ORM让数据库操作脱离SQL字符串拼接,避免因语法错误导致的调试黑洞;而模板引擎让前端同学不必啃Vue全家桶,用原生Django模板语法就能把ECharts数据塞进去。对比之下,Flask需要手动集成Flask-Admin、SQLAlchemy、Flask-Login,光配置就要写两百行代码——这对赶时间的学生是灾难。
其次是部署容错率。项目配套了uWSGI+nginx和Docker双部署方案,但底层逻辑是统一的:Django的manage.py runserver命令在开发环境零配置启动,而生产环境只需修改settings.py里的DEBUG=False和ALLOWED_HOSTS,其他全靠标准配置文件驱动。我见过太多FastAPI项目因为ASGI服务器选型(Uvicorn还是Hypercorn)、进程管理(supervisor还是systemd)或静态文件路径配置错误,在答辩前夜崩掉。Django的wsgi.py入口和uwsgi.ini配置是经过十年验证的“傻瓜式”组合,连运维实习生都能照着文档三分钟配好。
第三是数据一致性保障。网易云音乐数据存在天然关联:一首歌属于一个专辑,专辑属于一个歌手,评论指向一首歌。Django ORM的ForeignKey和ManyToManyField能用几行代码定义清晰的ER关系,自动生成迁移脚本,避免手写SQL时漏建外键约束。而Scrapy爬虫抓取的数据,通过pipeline直接调用Django model.save()入库,天然享受Django事务管理——当某条歌手信息入库失败时,整条歌曲记录会自动回滚,不会出现“有歌无歌手”的脏数据。这种保障在Flask里需要手动写SQL事务控制,对学生而言极易出错。
最后是文档生成友好性。Django的models.py字段注释、views.py函数docstring、urls.py路由说明,配合Sphinx工具能一键生成API文档。项目里提供的design_report.docx模板,其“数据库设计”章节直接引用Django模型定义生成的ER图,“接口说明”章节则从urls.py和views.py自动提取。这种文档与代码的强耦合,让毕设答辩时“文档与系统一致”不再是空话。
2.2 模块化分层:cloudmusic_django主应用如何承载业务流
整个系统采用经典的Django App分层架构,每个App承担明确职责,避免功能混杂:
-
cloudmusic_django 是主应用,负责全局配置(settings.py)、核心路由(urls.py)、首页视图(views.py)和基础模板(templates/base.html)。它的存在意义是提供“系统入口”,所有其他App都通过INSTALLED_APPS注册进来,形成松耦合依赖。
-
song_reco 是推荐模块,独立于主应用运行。它不处理爬虫或存储,只专注算法逻辑:接收歌曲ID列表,调用预训练的TF-IDF向量矩阵计算相似度,返回TOP10推荐结果。这种设计让推荐功能可单独测试——你可以在Django shell里执行
python manage.py shell,然后输入from song_reco.recommender import get_similar_songs; get_similar_songs(12345)直接验证算法效果,无需启动整个Web服务。 -
data_apply 是数据分析引擎,本质是Django的management command集合。它包含
python manage.py calculate_hot_score(计算歌曲热度分)、python manage.py analyze_sentiment(分析评论情感分布)、python manage.py generate_wordcloud(生成词云数据)等指令。这些命令在后台定时任务(如Linux cron)中调用,实现“数据计算与页面展示分离”——大屏页面只读取预计算好的结果表,避免每次刷新都触发耗时的SQL聚合查询。 -
admin后台 不是简单启用Django Admin,而是深度定制:在admin.py中重写了SongAdmin类,添加了“播放量趋势图”字段(通过iframe嵌入ECharts图表)、“热门评论预览”字段(截取最新3条评论)、“数据质量检查”按钮(执行数据完整性校验)。这种定制让导师在验收时,能直观看到数据健康度,而不是翻SQL查表。
这种分层不是为了炫技,而是解决实际痛点:当学生需要修改推荐算法时,只动song_reco目录;当需要调整热度计算公式时,只改data_apply里的command;当要更换大屏UI时,只改templates下的HTML文件。模块边界清晰,协作和调试成本直线下降。
2.3 数据流闭环:从爬虫到大屏的七步链路
整个系统最值得细品的是数据流动路径,它像一条精密流水线,环环相扣:
- Scrapy爬虫启动:执行
scrapy crawl netease_spider,爬虫从网易云音乐榜单页开始,解析歌曲ID列表; - 详情页抓取:根据ID请求歌曲详情页,提取歌名、歌手、专辑、播放量、评论数等字段;
- 评论抓取:对每首歌发起二级请求,获取前100条评论及点赞数;
- 数据清洗入库:Pipeline中调用Django ORM,将清洗后的数据存入MySQL。关键动作:歌手名称去重合并(如“周杰伦”和“Jay Chou”统一为“周杰伦”)、评论时间标准化(转为datetime格式)、播放量字符串转整型;
- 定时计算触发:Linux cron每小时执行
python manage.py calculate_hot_score,遍历所有歌曲,按公式热度分 = 播放量 × log(评论数 + 1) × 时间衰减系数重新计算并更新hot_score字段; - 大屏数据接口:views.py中的
dashboard_data视图,查询预计算好的热度榜、情感分布统计、词云高频词等结果表,序列化为JSON返回; - 前端动态渲染:index.html通过Ajax轮询
/api/dashboard/接口,ECharts收到数据后实时更新折线图、柱状图、词云图。
这条链路里藏着三个关键设计智慧:一是数据清洗前置,爬虫阶段就做标准化,避免后续分析被脏数据拖垮;二是计算与展示分离,所有耗时计算都在后台命令中完成,大屏页面只做轻量级数据读取;三是时间衰减机制,热度分公式里的时间衰减系数 = e^(-t/720)(t为小时数),确保新歌能快速上榜,老歌不会长期霸榜——这比单纯按播放量排序更符合真实音乐传播规律。
3. 核心细节解析:爬虫、存储、可视化三大模块实操要点
3.1 Scrapy爬虫:如何绕过网易云音乐的“温柔反爬”
网易云音乐的反爬策略属于“轻量级防御”,没有验证码和复杂JS加密,但设置了基础防护:User-Agent检测、Referer校验、请求频率限制。项目中的netease_spider爬虫不是暴力轮询,而是通过四层策略实现稳定采集:
第一层:请求头伪装
在spiders/netease_spider.py中,custom_settings覆盖默认headers:
custom_settings = {
'DEFAULT_REQUEST_HEADERS': {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Referer': 'https://music.163.com/',
}
}
这里的关键是Referer必须设为https://music.163.com/,否则榜单页返回403。我测试过,如果Referer为空或设为百度,服务器直接拒绝响应。
第二层:下载延迟与并发控制
在settings.py中配置:
DOWNLOAD_DELAY = 3 # 每次请求间隔3秒
CONCURRENT_REQUESTS = 1 # 并发请求数设为1
CONCURRENT_REQUESTS_PER_DOMAIN = 1
看似保守,实则精准:网易云音乐对单IP的请求频控阈值约2-3秒/次,设为3秒留出缓冲余量;并发设为1避免请求堆积触发风控。曾有学生把CONCURRENT_REQUESTS设为8,结果爬取10分钟后IP被封禁30分钟。
第三层:去重指纹管理
Scrapy默认的dupefilter基于request.url去重,但网易云音乐详情页URL含随机参数(如?userid=xxx),导致同一首歌被重复抓取。解决方案是在spider中重写start_requests方法,对URL进行标准化:
def start_requests(self):
for url in self.start_urls:
# 移除URL中的随机参数
clean_url = re.sub(r'\?[^&]+', '', url)
yield scrapy.Request(url=clean_url, callback=self.parse)
第四层:异常重试与日志追踪
在pipelines.py中添加RetryPipeline:
class RetryPipeline:
def process_item(self, item, spider):
if not item.get('song_name'):
spider.logger.error(f"Missing song_name for URL: {item.get('url')}")
raise DropItem("Song name missing")
return item
配合Scrapy的RETRY_TIMES=3设置,当页面解析失败时自动重试,同时记录详细日志。我在调试时发现,网易云音乐偶尔返回空白页面(HTTP 200但body为空),这种日志能快速定位是网络抖动还是反爬升级。
提示:爬虫首次运行建议先抓取10首歌测试,确认数据入库无误后再放开全量。项目预置的CSV示例数据(data/sample_songs.csv)就是这10首歌的清洗后版本,可直接导入MySQL验证流程。
3.2 MySQL存储设计:为什么用InnoDB而非SQLite?
项目默认配置使用MySQL,而非Django内置的SQLite,这是面向生产场景的务实选择。我们来看models.py中核心表的设计逻辑:
Song表(歌曲主表)
class Song(models.Model):
song_id = models.CharField(max_length=32, primary_key=True) # 网易云音乐歌曲ID,如'186016'
song_name = models.CharField(max_length=128)
artist = models.CharField(max_length=128)
album = models.CharField(max_length=128, blank=True)
play_count = models.BigIntegerField(default=0)
comment_count = models.IntegerField(default=0)
hot_score = models.FloatField(default=0.0) # 预计算热度分
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
关键设计点:song_id设为主键而非自增ID,因为网易云音乐ID是业务唯一标识,避免跨系统同步时ID冲突;play_count用BigIntegerField,因热门歌曲播放量超10亿,int类型会溢出;hot_score字段冗余存储,牺牲空间换时间,避免大屏查询时实时计算。
Comment表(评论子表)
class Comment(models.Model):
song = models.ForeignKey(Song, on_delete=models.CASCADE, related_name='comments')
content = models.TextField()
liked_count = models.IntegerField(default=0)
user_nickname = models.CharField(max_length=64, blank=True)
sentiment_score = models.FloatField(default=0.0) # -1~1情感分
created_at = models.DateTimeField()
这里用on_delete=models.CASCADE确保歌曲删除时评论级联清除,避免孤儿数据;related_name='comments'让查询更自然:song.comments.all()即可获取所有评论;sentiment_score字段在data_apply的analyze_sentiment命令中批量计算,而非爬虫实时计算——因为情感分析耗CPU,集中处理更高效。
数据库引擎选择InnoDB的核心原因:
- 支持事务(ACID),当一条歌曲记录入库失败时,关联的评论记录自动回滚;
- 行级锁,允许多个爬虫进程并发写入不同歌曲,避免SQLite的整库锁导致写入阻塞;
- 外键约束强制数据完整性,防止出现song_id在Song表不存在却存在于Comment表的情况;
- 支持全文索引,为后续可能的“歌词搜索”功能预留扩展空间。
注意:项目提供的SQL初始化脚本(sql/init_db.sql)包含创建数据库、用户、授权三步命令,执行前需修改root密码。若本地无MySQL,可用Docker快速启动:
docker run -d --name mysql-netease -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -v $(pwd)/mysql-data:/var/lib/mysql mysql:8.0。
3.3 可视化实现:ECharts动态渲染的“懒加载”技巧
大屏页面(templates/index.html)没有用Vue或React,而是纯Django模板+原生JavaScript,这是为降低学习门槛做的取舍。核心技巧在于“数据懒加载”——页面初始只渲染骨架,数据通过Ajax异步填充:
第一步:模板定义容器
<!-- 折线图容器 -->
<div id="playTrendChart" style="width: 100%; height: 400px;"></div>
<!-- 热度排行榜容器 -->
<div id="hotRankList" class="list-group"></div>
<!-- 词云图容器 -->
<div id="wordCloudChart" style="width: 100%; height: 500px;"></div>
第二步:JavaScript轮询接口
// 每30秒拉取一次最新数据
setInterval(function() {
$.getJSON('/api/dashboard/', function(data) {
// 更新折线图
const trendChart = echarts.init(document.getElementById('playTrendChart'));
trendChart.setOption({
xAxis: { data: data.trend_dates },
series: [{ data: data.play_counts }]
});
// 更新排行榜
$('#hotRankList').empty();
data.hot_songs.forEach(song => {
$('#hotRankList').append(`
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">${song.song_name}</h5>
<small class="text-muted">${song.hot_score.toFixed(2)}</small>
</div>
<p class="mb-1">${song.artist}</p>
</a>
`);
});
});
}, 30000);
关键优化点:
- 防抖处理:实际代码中加入了clearTimeout防抖,避免网络延迟导致多次轮询叠加;
- 错误降级:当Ajax失败时,保留上次成功渲染的数据,显示“数据更新中…”提示,而非白屏;
- 内存释放:每次重绘前调用trendChart.dispose()销毁旧实例,防止ECharts内存泄漏——这是学生项目中最常忽略的坑,连续运行24小时后浏览器卡死多半因此;
- 响应式适配:在window.resize事件中监听,调用trendChart.resize()自动适配屏幕尺寸。
实操心得:首次调试时,先在浏览器控制台执行
$.getJSON('/api/dashboard/')确认接口返回JSON结构正确,再写渲染逻辑。项目预置的data/sample_dashboard.json就是该接口的模拟返回,可用来测试前端逻辑。
4. 实操过程:从零部署到数据大屏上线的完整流程
4.1 环境准备:Python 3.8与依赖安装的避坑指南
项目声明支持Python 3.8,这是经过深思熟虑的选择:
- Python 3.9+的某些语法(如PEP 604联合类型)在Django 3.2中不兼容;
- Python 3.7以下缺少dataclasses模块,影响Scrapy部分组件;
- 3.8是Django 3.2官方支持的最后一个稳定版本,兼容性最佳。
安装步骤与常见陷阱:
1. 创建虚拟环境:python3.8 -m venv venv(注意不要用virtualenv,避免pip版本冲突);
2. 激活环境:source venv/bin/activate(Mac/Linux)或venv\Scripts\activate(Windows);
3. 升级pip:pip install --upgrade pip(必须!旧版pip安装Scrapy会报错);
4. 安装依赖:pip install -r requirements.txt。
requirements.txt关键依赖解析:
- Django==3.2.25:LTS长期支持版本,安全更新持续到2024年;
- scrapy==2.6.2:与Python 3.8兼容的最新稳定版,避免2.7+的asyncio冲突;
- pymysql==1.0.2:MySQL连接驱动,比mysqlclient编译更简单;
- echarts-python==0.1.10:非必需,但提供Python端生成ECharts配置的便利;
- snowlp==0.12.22:轻量级中文情感分析库,比jieba+自定义词典更准。
常见问题:Windows下安装pymysql报错“Microsoft Visual C++ 14.0 is required”。解决方案:安装Microsoft C++ Build Tools,或改用
pip install PyMySQL(纯Python实现,无需编译)。
4.2 数据库初始化:从SQL脚本到Django迁移的衔接
项目提供两种数据初始化方式,针对不同场景:
方式一:SQL脚本直接导入(适合快速验证)
1. 登录MySQL:mysql -u root -p;
2. 创建数据库:CREATE DATABASE cloudmusic DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;;
3. 导入初始化数据:source sql/init_db.sql(含建表语句);
4. 导入示例数据:source sql/sample_data.sql(含100首歌+500条评论)。
方式二:Django迁移(适合二次开发)
1. 修改settings.py中的DATABASES配置,填入你的MySQL账号;
2. 执行迁移:python manage.py makemigrations && python manage.py migrate;
3. 创建超级用户:python manage.py createsuperuser;
4. 加载示例数据:python manage.py loaddata data/fixtures/songs.json(fixtures是Django标准数据导出格式)。
关键衔接点:SQL脚本中的表名与Django模型保持一致(如song_song对应Song模型),但Django迁移会自动添加id自增主键字段,而SQL脚本中song_id是主键。因此,若先运行SQL再执行migrate,会因主键冲突报错。正确顺序是:先migrate建表,再loaddata或source sample_data.sql导入数据。
注意:sample_data.sql中的中文字符必须用UTF8MB4编码保存,否则导入后出现乱码。用Notepad++打开,编码→转为UTF-8-BOM可解决。
4.3 启动服务:开发模式与生产模式的切换逻辑
开发模式(一键启动):
python manage.py runserver 0.0.0.0:8000
- 自动开启DEBUG=True,代码修改后热重载;
- 静态文件由Django自动serve,无需额外配置;
- 访问http://localhost:8000即可看到大屏,http://localhost:8000/admin进入后台。
生产模式(uWSGI+nginx):
1. 安装uWSGI:pip install uwsgi;
2. 启动uWSGI:uwsgi --ini uwsgi.ini(配置文件指定socket、进程数、虚拟环境路径);
3. 配置nginx反向代理,将80端口请求转发至uWSGI socket;
4. 关闭DEBUG,设置ALLOWED_HOSTS=[‘your-domain.com’]。
Docker一键部署(推荐给懒人):
项目根目录执行:
docker-compose up -d # 启动MySQL+Django+nginx三容器
docker-compose logs -f # 查看实时日志
docker-compose.yml已预置网络配置,Django容器能自动发现MySQL容器IP,无需修改settings.py。
实操心得:首次启动时,若大屏显示“数据加载失败”,先检查
python manage.py showmigrations确认所有迁移已应用;再执行python manage.py calculate_hot_score手动触发热度计算;最后查看logs/scrapy.log确认爬虫是否正常运行。
4.4 后台管理:Admin定制化开发的三个实用技巧
Django Admin不是摆设,而是数据治理的核心工具。项目在admin.py中做了三项关键定制:
技巧一:自定义字段显示
@admin.register(Song)
class SongAdmin(admin.ModelAdmin):
list_display = ('song_name', 'artist', 'play_count', 'comment_count', 'hot_score', 'updated_at')
list_filter = ('artist', 'updated_at') # 右侧筛选栏
search_fields = ('song_name', 'artist') # 顶部搜索框
readonly_fields = ('created_at', 'updated_at') # 只读字段
list_display定义列表页显示字段,避免默认只显示__str__;list_filter添加按歌手、时间筛选,方便导师快速找特定数据。
技巧二:内联编辑关联数据
class CommentInline(admin.TabularInline):
model = Comment
extra = 0 # 默认不显示空行
fields = ('content', 'liked_count', 'sentiment_score')
@admin.register(Song)
class SongAdmin(admin.ModelAdmin):
inlines = [CommentInline] # 在歌曲编辑页内嵌评论
这样编辑一首歌时,可直接在同一页增删改评论,无需跳转,大幅提升数据修正效率。
技巧三:自定义操作按钮
@admin.action(description='重新计算热度分')
def recalculate_hot_score(modeladmin, request, queryset):
from data_apply.management.commands.calculate_hot_score import Command
cmd = Command()
cmd.handle()
@admin.register(Song)
class SongAdmin(admin.ModelAdmin):
actions = [recalculate_hot_score] # 列表页批量操作按钮
选中多首歌后,点击“重新计算热度分”,后台自动执行算法,比手动敲命令更直观。
注意:Admin页面的图表展示(如播放量趋势图)是通过iframe嵌入
/chart/song_trend/<song_id>/接口实现的,该接口返回ECharts JSON配置,前端用<iframe src="...">加载。这种方式避免Admin模板与ECharts JS冲突。
5. 常见问题与排查技巧实录:那些踩过的坑,现在帮你绕开
5.1 爬虫相关问题速查表
| 问题现象 | 排查思路 | 解决方案 |
|---|---|---|
| 爬虫启动后无日志输出,进程立即退出 | 检查spider文件路径是否在scrapy.cfg同级目录;确认scrapy crawl netease_spider命令中的spider名与spider类名一致 | 在spiders目录下执行ls确认netease_spider.py存在;检查类定义class NeteaseSpider(scrapy.Spider):,name属性是否为name = 'netease_spider' |
| 爬取页面返回403 Forbidden | 检查请求头Referer是否缺失或错误;确认User-Agent是否被识别为爬虫 | 在settings.py中添加DEFAULT_REQUEST_HEADERS,Referer必须为https://music.163.com/;User-Agent换成主流浏览器标识 |
| 数据入库时提示“Data truncated for column ‘play_count’” | MySQL字段类型与Django模型不匹配;play_count字段在MySQL中定义为INT而非BIGINT | 执行ALTER TABLE song_song MODIFY COLUMN play_count BIGINT DEFAULT 0;;或重新运行python manage.py migrate --fake-initial |
| 评论抓取数量远少于页面显示数(如页面显示1000条评论,只抓到200条) | 网易云音乐评论分页加载,爬虫未处理AJAX接口 | 查看浏览器Network面板,找到/weapi/v1/resource/comments/MUSIC_ID接口,用Scrapy模拟POST请求(需逆向加密参数) |
5.2 数据库与Django连接问题
| 问题现象 | 排查思路 | 解决方案 |
|---|---|---|
django.db.utils.OperationalError: (1045, "Access denied for user 'root'@'localhost'") | settings.py中DATABASES配置的用户名密码错误;MySQL未授权远程访问 | 登录MySQL执行GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password'; FLUSH PRIVILEGES;;或修改settings.py为本地连接'HOST': '127.0.0.1' |
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module | 未安装PyMySQL或mysqlclient;Python与MySQL版本不兼容 | pip install PyMySQL;在settings.py顶部添加import pymysql; pymysql.install_as_MySQLdb() |
django.db.utils.ProgrammingError: relation "song_song" does not exist | 未执行migrate命令;迁移文件损坏 | 执行python manage.py showmigrations查看未应用迁移;若显示[ ] 0001_initial,则运行python manage.py migrate |
5.3 可视化与前端问题
| 问题现象 | 排查思路 | 解决方案 |
|---|---|---|
大屏页面空白,控制台报echarts is not defined | static/js/echarts.min.js未正确加载;路径错误 | 检查templates/base.html中<script src="{% static 'js/echarts.min.js' %}"></script>;确认static目录结构为static/js/echarts.min.js |
| 折线图显示“无数据”,但Ajax接口返回JSON正常 | ECharts配置项错误;xAxis.data与series.data长度不一致 | 在浏览器控制台打印data.trend_dates和data.play_counts,确认两者长度相同;检查ECharts setOption中xAxis.type是否为'category' |
| 词云图文字重叠、显示不全 | canvas尺寸过小;ECharts词云配置参数不合理 | 在wordCloudChart容器div上添加style="width: 100%; height: 500px;";ECharts配置中增加grid: { left: '3%', right: '4%', bottom: '3%', top: '3%' } |
5.4 部署与性能问题
| 问题现象 | 排查思路 | 解决方案 |
|---|---|---|
| uWSGI启动后访问502 Bad Gateway | nginx未正确代理到uWSGI socket;socket路径不匹配 | 检查uwsgi.ini中socket = /tmp/uwsgi.sock;确认nginx配置中proxy_pass unix:///tmp/uwsgi.sock;路径一致 |
Docker启动后Django容器报Can't connect to MySQL server | 容器网络未互通;MySQL未完全启动Django就尝试连接 | 在docker-compose.yml中为Django服务添加depends_on: [mysql];或在Django启动脚本中加入重试逻辑(如while ! nc -z db 3306; do sleep 1; done) |
| 大屏刷新缓慢,Ajax请求超时 | MySQL查询未加索引;热度计算未预缓存 | 在Song表的hot_score字段上创建索引:CREATE INDEX idx_hot_score ON song_song(hot_score);;确认calculate_hot_score命令已定时执行 |
最后分享一个小技巧:当需要快速验证某个功能模块时,不要重启整个服务。比如想测试推荐算法,直接运行
python manage.py shell,然后from song_reco.recommender import *; print(get_similar_songs(12345));想测试数据计算,运行python manage.py analyze_sentiment --limit=100(–limit参数限制处理数量,避免全量扫描)。这种“模块化调试”能节省80%的等待时间。
我在实际带毕设时发现,90%的问题都集中在爬虫请求头、数据库连接配置、ECharts数据格式这三点上。只要把这三个环节的检查清单背下来,项目80%的故障都能自己搞定。剩下的20%,往往是环境差异导致的边角问题——比如Mac和Windows的路径分隔符、Linux和Windows的换行符,这些在README.md里都有标注,遇到时别慌,对照文档逐行检查就行。
简介:用Django开发的网易云音乐数据分析平台,内置Scrapy爬虫自动抓取歌曲、歌手、评论等公开数据,支持存入本地MySQL数据库;前端通过动态图表展示播放量、热度排行、用户评论情感分布等核心指标,形成实时更新的数据大屏;系统包含cloudmusic_django主应用、song_reco推荐模块、data_apply分析逻辑、admin后台管理界面,以及清晰的models定义和URL路由;提供README说明文档和设计报告模板,覆盖需求分析、技术选型、数据库ER图、API接口列表与Docker/uWSGI部署流程;预置CSV示例数据和SQL初始化脚本,也兼容自定义爬取结果;Python 3.8环境一键运行,无需额外配置即可启动开发服务器查看效果;适合计算机、软件工程类专业学生做毕业设计或课程实训,教师也可用于教学演示与项目指导。


被折叠的 条评论
为什么被折叠?



