博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅点击查看作者主页,了解更多项目!
🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅
1、毕业设计:2026年计算机专业毕业设计选题汇总(建议收藏)✅
2、大数据毕业设计:2026年选题大全 深度学习 python语言 JAVA语言 hadoop和spark(建议收藏)✅
1、项目介绍
- 技术栈:Python语言、Django框架、MySQL数据库、协同过滤推荐算法(基于用户+基于物品)、Echarts可视化、HTML、词云分析(评论/标签关键词提取)
- 核心功能:个性化电影推荐(协同过滤驱动)、电影数据多维度可视化(评分/类型分布等)、词云分析(热门标签/评论关键词)、用户交互(注册登录、收藏、搜索、评分)、电影信息展示
- 研究背景:随着电影内容爆发式增长,用户面临“选片难”痛点——传统推荐依赖热门榜单,无法匹配个人偏好;同时电影数据(评分、类型、用户评论)分散,缺乏直观分析工具,导致用户难以快速把握电影特征与市场趋势,亟需“精准推荐+可视化分析”一体化系统解决。
- 研究意义:技术层面,通过Django搭建稳定后端,协同过滤算法提升推荐精度,Echarts与词云实现数据可视化,构建“交互-推荐-分析”完整技术链;用户层面,为电影爱好者提供个性化推荐与直观数据洞察,减少选片时间;学习层面,完整覆盖“Web开发+推荐算法+数据可视化”全流程,适合作为毕业设计或实战项目,具备实用与学习双重价值。
2、项目界面
- 电影数据可视化分析
- 电影首页
- 我的收藏
- 电影搜索查询
- 电影推荐—协同过滤推荐算法
- 注册登录界面
3、项目说明
本项目是基于Python+Django框架开发的电影个性化推荐与分析系统,整合协同过滤算法、Echarts可视化、词云分析与MySQL数据库,核心实现“用户交互-个性化推荐-数据可视化”的完整流程,旨在解决电影筛选低效、推荐不精准、数据洞察不足的问题。
(1)系统架构与技术逻辑
- 架构设计:采用Django“MVT(模型-视图-模板)”架构,分层清晰:
- 模型层(Model):MySQL存储核心数据,包括电影信息(标题、评分、类型、演员、地区)、用户数据(账号、评分记录、收藏列表)、交互日志(搜索关键词、评论内容),为算法与可视化提供支撑;
- 视图层(View):Django后端处理业务逻辑,包括协同过滤算法调度、用户请求响应(登录/收藏/搜索)、数据统计(为可视化提供数据源),通过视图函数与模板交互;
- 模板层(Template):基于HTML构建前端界面,嵌入Echarts组件实现可视化图表,结合Django模板语法渲染动态内容(如推荐列表、收藏记录),确保界面交互流畅;
- 核心流程:用户注册登录→交互操作(搜索/评分/收藏)→数据存入MySQL→协同过滤算法生成个性化推荐→Echarts/词云将数据转化为可视化结果→用户在前端查看推荐与分析。
(2)核心功能模块详解
① 用户交互模块(基础体验)
- 身份管理:通过“注册登录界面”实现用户认证,支持账号注册(填写基本信息)、密码登录、信息修改,Django后端通过ORM操作MySQL存储用户数据,保障账号安全;
- 电影浏览与操作:
- 电影首页:展示热门电影(按评分/浏览量排序)、分类入口(按类型/地区筛选)、个性化推荐区(登录用户可见),用户点击可进入详情页;
- 我的收藏:集中管理用户收藏的电影,支持按“收藏时间”“电影评分”排序,可直接取消收藏,操作实时同步至MySQL;
- 电影搜索查询:支持关键词搜索(电影名、演员、类型),结果页展示匹配电影的封面、评分、简介,快速定位目标内容。
② 协同过滤推荐模块(核心技术)
- 算法实现:结合“基于用户”与“基于物品”的协同过滤,提升推荐精准度:
- 基于用户的协同过滤:
- 逻辑:计算目标用户与其他用户的兴趣相似度(如共同评分的电影数量、评分偏差),筛选“高相似度用户”,推荐其高分且目标用户未浏览的电影;
- 基于物品的协同过滤:
- 逻辑:分析电影间的关联(如同一类型、共同演员、用户同时评分),计算电影相似度,推荐“与用户收藏/高分电影相似度高”的影片;
- 基于用户的协同过滤:
- 算法优化:
- 时间衰减因子:对用户历史评分加权,近期评分权重更高(如3个月内评分权重×1.2),避免过时偏好影响推荐;
- 多样性补充:加入少量随机推荐(占比10%),平衡精准度与多样性,避免推荐结果单一;
- 推荐展示:在“电影推荐”页面专门展示算法结果,标注“为你推荐”,并附推荐理由(如“与你喜欢的《XX》相似度92%”)。
③ 数据可视化与词云分析模块(数据洞察)
- Echarts可视化分析:通过多维度图表直观呈现电影数据规律:
- 电影数据可视化分析页面:包含“各评分区间电影数量柱状图”“不同类型电影占比饼图”“年度电影上映数量折线图”,帮助用户把握电影质量与市场趋势;
- 关联分析:如“评分与地区分布热力图”(展示不同地区电影的平均评分),辅助用户发现“高评分地区电影”(如欧洲剧情片平均分8.2);
- 词云分析:从电影标签、用户评论中提取高频关键词(如“治愈”“悬疑”“反转”),生成词云图(词大小反映频率),直观呈现当前热门电影主题,帮助用户快速识别兴趣点(如词云高频“科幻”则推荐更多科幻片)。
④ 数据存储与管理模块(支撑核心)
- MySQL数据库设计:核心表结构包括:
- 电影表:存储标题、评分、类型、演员、地区、简介等基础信息;
- 用户表:存储账号、密码(加密)、注册时间等;
- 评分表:记录用户ID、电影ID、评分值、评分时间;
- 收藏表:关联用户与电影,记录收藏时间;
- Django ORM操作:通过模型类简化数据库操作,如查询“用户收藏的电影”“某类型电影的平均评分”,无需编写原生SQL,提升开发效率。
4、核心代码
# 验证登录defcheck_login(func):defwrapper(request):# print("装饰器验证登录")cookie=request.COOKIES.get('uid')ifnotcookie:returnredirect('/login/')else:returnfunc(request)returnwrapper# Create your views here.@check_logindefindex(request):uid=int(request.COOKIES.get('uid',-1))ifuid!=-1:username=User.objects.filter(id=uid)[0].name relions=Movie.objects.all()all_type={item.regionsforiteminrelions}# all_type = ['历城', '天桥', '长清', '章丘', '高新', '市中', '济阳', '槐荫', '历下']if'type'notinrequest.GET:# 新闻类别type_='中国大陆'newlist=Movie.objects.filter(regions__contains=type_).values()else:type_=request.GET.get('type')newlist=Movie.objects.filter(regions__contains=type_).values()tmp=[]foriteminnewlist:ifLike.objects.filter(uid_id=uid,hid_id=item['id']):is_like=1else:is_like=0item['is_like']=is_like tmp.append(item)newlist=tmpreturnrender(request,'index.html',locals())defstar_ajax(request):res={}yid=int(request.POST.get('id'))uid=int(request.COOKIES.get('uid',-1))ifLike.objects.filter(uid_id=uid,hid_id=yid):Like.objects.filter(uid_id=uid,hid_id=yid).delete()res['color']='black'else:Like.objects.create(uid_id=uid,hid_id=yid)res['color']='red'returnJsonResponse(res)defmy_shoucang(request):uid=int(request.COOKIES.get('uid',-1))ifuid!=-1:username=User.objects.filter(id=uid)[0].name newlist=[]ifLike.objects.filter(uid_id=uid):newlist=Like.objects.filter(uid_id=uid)id_list=[item.hid_idforiteminnewlist]newlist=Movie.objects.filter(id__in=id_list).values()tmp=[]foriteminnewlist:ifLike.objects.filter(uid_id=uid,hid_id=item['id']):is_like=1else:is_like=0item['is_like']=is_like tmp.append(item)newlist=tmpreturnrender(request,'my_shoucang.html',locals())@check_logindefdetail(request):uid=int(request.COOKIES.get('uid',-1))ifuid!=-1:username=User.objects.filter(id=uid)[0].name id_=request.GET.get('id')info=House.objects.get(id=int(id_))ifSee.objects.filter(uid_id=uid):See.objects.filter(uid_id=uid).update(num=F('num')+1)else:See.objects.create(uid_id=uid,hid_id=int(id_),num=1)returnrender(request,'detail_new.html',locals())defscrawl_item(request):""" 爬取所有的电影元数据 :param request: :return: """foriintqdm(range(0,201,20)):# url = f'https://movie.douban.com/j/chart/top_list?type=10&interval_id=10:90&action=None&start={i}&limit=20'url="https://movie.douban.com/j/chart/top_list"payload={"type":10,"interval_id":"100:90","action":None,"start":i,"limit":20}headers={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"}res=requests.get(url=url,params=payload,headers=headers,)time.sleep(10)data_jsons=res.json()fordata_jsonindata_jsons:id_=data_json['id']# intid_=int(id_)# rating = data_json['rating'][0]# floatrank=data_json['rank']# intrank=int(rank)img=data_json['cover_url']isPlayable=data_json['is_playable']kind=data_json['types']# listkind=','.join(kind)regions=data_json['regions'][0]title=data_json['title']url=data_json['url']releaseDate=data_json['release_date']actorCount=data_json['actor_count']# intactorCount=int(actorCount)voteNum=data_json['vote_count']# intvoteNum=int(voteNum)score=data_json['score']# floatscore=float(score)actors=data_json['actors']# listactors=','.join(actors)# print(id_,rank,img,isPlayable,kind,regions,title,url,releaseDate,actorCount,voteNum,score,actors)ifnotMovie.objects.filter(id=id_):try:Movie.objects.create(id=id_,rank=rank,img=img,isPlayable=isPlayable,kind=kind,regions=regions,title=title,url=url,releaseDate=releaseDate,actorCount=actorCount,voteNum=voteNum,score=score,actors=actors)except:continuereturnHttpResponse('全部电影元数据已经爬取OK')defscrawl_comment(request):""" 爬取所有的电影元数据 :param request: :return: """returnHttpResponse('全部电影评论已经爬取OK')@check_logindeftuijian(request):uid=int(request.COOKIES.get('uid',-1))ifuid!=-1:username=User.objects.filter(id=uid)[0].name train=dict()history=Like.objects.all()# 0.1foriteminhistory:ifitem.uid_idnotintrain.keys():train[item.uid_id]={item.hid_id:uid}else:train[item.uid_id][item.hid_id]=train[item.uid_id].get(item.hid_id,0)+10history=See.objects.all()# 0.1foriteminhistory:ifitem.uid_idnotintrain.keys():train[item.uid_id]={item.hid_id:0.1*item.num}else:train[item.uid_id][item.hid_id]=train[item.uid_id].get(item.hid_id,0)+1*item.num# 声明一个的对象newlist=[]try:item=KNN(train)item.ItemSimilarity()recommedDict=item.Recommend(int(uid))# 字典newlist=Movie.objects.filter(id__in=list(recommedDict.keys()))except:print("协同过滤异常啦")passiflen(newlist)==0:msg="你还没有在该网站有过评论、浏览行为,请去浏览吧!"newlist=Movie.objects.order_by('-id')[:10].values()else:msg=""#tmp=[]print(newlist)foriteminnewlist:try:id=item["id"]except:id=item.idifLike.objects.filter(uid_id=uid,hid_id=id):is_like=1else:is_like=0try:item['is_like']=is_likeexcept:item.is_like=is_like tmp.append(item)newlist=tmpreturnrender(request,'tuijian.html',locals())deftest(request):returnHttpResponse('测试完成')@check_logindefsearch(request):uid=int(request.COOKIES.get('uid',-1))ifuid!=-1:username=User.objects.filter(id=uid)[0].name newlist=[]ifrequest.method=='POST':keywords=request.POST.get('keywords')newlist=Movie.objects.filter(title__contains=keywords).values()tmp=[]foriteminnewlist:ifLike.objects.filter(uid_id=uid,hid_id=item['id']):is_like=1else:is_like=0item['is_like']=is_like tmp.append(item)newlist=tmpelse:keywords=''returnrender(request,'search.html',locals())deflogin(request):ifrequest.method=="POST":tel,pwd=request.POST.get('tel'),request.POST.get('pwd')ifUser.objects.filter(tel=tel,password=pwd):obj=redirect('/')obj.set_cookie('uid',User.objects.filter(tel=tel,password=pwd)[0].id,max_age=60*60*24)returnobjelse:msg="用户信息错误,请重新输入!!"returnrender(request,'login.html',locals())else:returnrender(request,'login.html',locals())defregister(request):ifrequest.method=="POST":name,tel,pwd=request.POST.get('name'),request.POST.get('tel'),request.POST.get('pwd')print(name,tel,pwd)ifUser.objects.filter(tel=tel):msg="你已经有账号了,请登录"else:User.objects.create(name=name,tel=tel,password=pwd)msg="注册成功,请登录!"returnrender(request,'login.html',locals())else:msg=""returnrender(request,'register.html',locals())deflogout(request):obj=redirect('/')obj.delete_cookie('uid')returnobjdefplot(request):raw_data=Movie.objects.all()# 1 每个国家 电影排行榜main1=raw_data.values('regions').annotate(count=Count('regions')).order_by('-count')[:10]main1_x=[item['regions']foriteminmain1]main1_y=[item['count']foriteminmain1]# 2 每年电影排行year_list=list(range(1999,2020))main2_x=year_list main2_y=[]foryearinyear_list:main2_y.append(raw_data.filter(releaseDate__year=year).count())# print(main1)# 3 类别被购买前十tmp=[item.actorsforiteminraw_data]result_list=[]foritemintmp:result_list=result_list+item.split(',')result_dict={k:result_list.count(k)forkinresult_list}result_dict=sorted(result_dict.items(),key=lambdax:x[1],reverse=True)# 最大到最小print(result_dict)main3=[{'value':item[1],'name':item[0]}foriteminresult_dict]tmp=[item.kindforiteminraw_data]result_list=[]foritemintmp:result_list=result_list+item.split(',')result_dict={k:result_list.count(k)forkinresult_list}result_dict=sorted(result_dict.items(),key=lambdax:x[1],reverse=True)[:5]# 最大到最小print(result_dict)main4=[{'value':item[1],'name':item[0]}foriteminresult_dict]main4_x=[item['name']foriteminmain4]returnrender(request,'plot.html',locals())5、源码获取方式
🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅
感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻