博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅

点击查看作者主页,了解更多项目!

🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅

1、毕业设计:2026年计算机专业毕业设计选题汇总(建议收藏)✅

2、大数据毕业设计:2026年选题大全 深度学习 python语言 JAVA语言 hadoop和spark(建议收藏)✅

1、项目介绍

技术栈
本项目采用Python作为开发主语言,依托Django框架搭建系统,使用MySQL数据库存储各类数据,融合基于用户和物品的协同过滤推荐算法打造核心推荐能力,借助Echarts实现数据可视化,以HTML构建前端界面,并运用词云分析技术提取评论和标签中的核心关键词。

功能模块

  • 用户交互模块
  • 协同过滤推荐模块
  • 数据可视化与词云分析模块
  • 数据存储与管理模块
  • 电影数据可视化分析
  • 电影首页
  • 我的收藏
  • 电影搜索查询
  • 电影推荐
  • 注册登录界面

项目介绍
本项目是基于Python和Django框架开发的电影个性化推荐与分析系统,整合协同过滤算法、Echarts可视化、词云分析及MySQL数据库,搭建起“用户交互-个性化推荐-数据可视化”的完整流程。系统针对电影筛选低效、推荐不精准、数据洞察不足的痛点,既为用户提供个性化推荐、收藏、搜索等基础交互功能,也通过多维度可视化图表和词云分析,帮助用户直观掌握电影数据特征与市场趋势,兼具实用价值与学习价值。

2、项目界面

电影数据可视化分析
以柱状图展示国家电影数量排行,用折线图呈现近 20 年电影数量变化,用词云图呈现演员相关关键词,通过饼图展示电影类别的分布,这些图表可分别帮助用户直观了解电影的地域分布、产量趋势、演员关联信息及类型占比情况。
在这里插入图片描述

电影首页
该页面上方提供不同国家 / 地区的筛选选项,下方展示对应筛选结果的电影列表,每条目包含电影封面、名称、主创人员、年份、地区、类型、评分、演员数、评价数及收藏按钮,可帮助用户按地域筛选电影并查看详细信息、进行收藏操作。
在这里插入图片描述

我的收藏
该页面展示了用户收藏的电影列表,每条目包含电影封面、名称、主创人员、年份、地区、类型、评分、演员数、评价数及已点亮的收藏按钮,可帮助用户集中查看自己收藏的电影信息,直观了解各收藏电影的详细内容并确认收藏状态。
在这里插入图片描述

电影搜索查询
页面上方有搜索框和搜索按钮,下方呈现对应关键词的电影列表,每条目配有电影封面,同时展示名称、主创、年份、地区、类型、评分等信息,还设有收藏按钮,可帮助用户快速获取搜索到的电影详情并进行收藏操作。

在这里插入图片描述

电影推荐—协同过滤推荐算法
该页面展示了系统推荐的电影列表,每条目配有电影封面,同时呈现电影名称、主创人员、年份、地区、类型、评分、演员数、评价数等信息,还设有收藏按钮,可帮助用户查看推荐的电影详情并进行收藏操作。
在这里插入图片描述

注册登录界面
页面以夜景为背景,展示了系统标识与登录界面,包含账号、密码输入框及登录按钮,还设有注册入口,可帮助用户完成账号登录或注册操作,是进入系统使用后续功能的入口页面。
在这里插入图片描述

3、项目说明

一、技术栈
本项目以Python为核心开发语言,基于Django框架搭建整体系统架构,采用MySQL数据库存储电影信息、用户数据等各类核心数据;融合基于用户与物品的协同过滤推荐算法实现个性化推荐,借助Echarts完成多维度数据可视化呈现,以HTML构建前端交互界面,并运用词云分析技术提取电影评论和标签中的核心关键词。

二、功能模块

  • 用户交互模块:包含注册登录与电影操作两大核心能力,注册登录界面支持账号注册、密码登录,是使用系统的入口;电影操作涵盖按地域筛选电影、收藏电影、关键词搜索电影等,满足用户基础的浏览与交互需求。
  • 协同过滤推荐模块:作为系统核心技术模块,结合用户与物品双维度协同过滤逻辑,计算用户或电影间的相似度,生成个性化推荐列表,在电影推荐页面展示结果,助力用户发现符合偏好的影片。
  • 数据可视化与词云分析模块:在电影数据可视化分析页面,通过柱状图、折线图、饼图展示电影地域分布、产量趋势、类型占比等规律,同时用词云图呈现演员、评论相关关键词,直观展现电影数据特征。
  • 数据存储与管理模块:依托MySQL数据库搭建电影表、用户表、评分表、收藏表等核心表结构,通过Django ORM简化数据库操作,高效存储和管理各类数据,为全系统提供数据支撑。
  • 电影数据可视化分析:专门呈现多维度电影数据图表的页面,涵盖国家电影数量排行柱状图、近20年电影数量变化折线图等,帮助用户洞察电影市场趋势与特征。
  • 电影首页:系统核心浏览页面,提供不同国家/地区筛选选项,展示筛选后的电影列表,每条目包含封面、评分等完整信息,支持收藏操作,方便用户浏览和筛选电影。
  • 我的收藏:集中展示用户收藏电影的页面,列表包含电影封面、主创、评分等信息,收藏按钮标注已收藏状态,便于用户管理和查看收藏内容。
  • 电影搜索查询:支持关键词检索的功能页面,上方设搜索框与按钮,下方展示匹配的电影列表及详情,支持收藏,帮助用户快速定位目标电影。
  • 电影推荐:展示协同过滤算法推荐结果的页面,列表呈现推荐电影的封面、评分等信息,支持收藏,为用户推送个性化影片。
  • 注册登录界面:系统身份验证入口,以夜景为背景,包含账号、密码输入框和登录按钮,设有注册入口,完成用户身份认证后才可使用收藏、推荐等核心功能。

三、项目总结
本电影个性化推荐与分析系统围绕用户“选片难、数据洞察难”的核心痛点构建,整合Python、Django、MySQL等技术,将协同过滤推荐与Echarts可视化结合,形成“交互-推荐-分析”的完整闭环。系统既通过注册登录、收藏、搜索等功能满足用户基础交互需求,又凭借精准的个性化推荐和多维度数据可视化分析,帮助用户高效筛选电影、洞察市场趋势,不仅具备实际应用价值,也完整覆盖Web开发、推荐算法、数据可视化等技术点,适合作为学习实践或毕业设计项目。

4、核心代码

# 验证登录
def check_login(func):
    def wrapper(request):
        # print("装饰器验证登录")
        cookie = request.COOKIES.get('uid')
        if not cookie:
            return redirect('/login/')
        else:
            return func(request)

    return wrapper


# Create your views here.
@check_login
def index(request):


    uid = int(request.COOKIES.get('uid', -1))
    if uid != -1:
        username = User.objects.filter(id=uid)[0].name

    relions = Movie.objects.all()
    all_type = {item.regions for item in relions}
    # all_type = ['历城', '天桥', '长清', '章丘', '高新', '市中', '济阳', '槐荫', '历下']

    if 'type' not in request.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 = []
    for item in newlist:
        if Like.objects.filter(uid_id=uid, hid_id=item['id']):
            is_like = 1
        else:
            is_like = 0
        item['is_like'] = is_like
        tmp.append(item)
    newlist = tmp
    return render(request, 'index.html', locals())


def star_ajax(request):
    res = {}
    yid = int(request.POST.get('id'))
    uid = int(request.COOKIES.get('uid', -1))

    if Like.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'
    return JsonResponse(res)




def my_shoucang(request):
    uid = int(request.COOKIES.get('uid', -1))
    if uid != -1:
        username = User.objects.filter(id=uid)[0].name

    newlist = []
    if Like.objects.filter(uid_id=uid):
        newlist = Like.objects.filter(uid_id=uid)
    id_list = [item.hid_id for item in newlist]
    newlist = Movie.objects.filter(id__in=id_list).values()
    tmp = []
    for item in newlist:
        if Like.objects.filter(uid_id=uid, hid_id=item['id']):
            is_like = 1
        else:
            is_like = 0
        item['is_like'] = is_like
        tmp.append(item)
    newlist = tmp
    return render(request, 'my_shoucang.html', locals())



@check_login
def detail(request):
    uid = int(request.COOKIES.get('uid', -1))
    if uid != -1:
        username = User.objects.filter(id=uid)[0].name
    id_ = request.GET.get('id')
    info = House.objects.get(id=int(id_))
    if See.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)
    return render(request, 'detail_new.html', locals())



def scrawl_item(request):
    """
    爬取所有的电影元数据
    :param request:
    :return:
    """
    for i in tqdm( 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()
        for data_json in data_jsons:
            id_ = data_json['id']#  int
            id_ = int(id_)
            # rating = data_json['rating'][0]#  float
            rank = data_json['rank']#  int
            rank = int(rank)
            img = data_json['cover_url']
            isPlayable = data_json['is_playable']
            kind = data_json['types'] # list
            kind = ','.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']#  int
            actorCount = int(actorCount)
            voteNum = data_json['vote_count']#  int
            voteNum = int(voteNum)
            score = data_json['score'] #  float
            score = float(score)
            actors = data_json['actors']  # list
            actors = ','.join(actors)
            # print(id_,rank,img,isPlayable,kind,regions,title,url,releaseDate,actorCount,voteNum,score,actors)
            if not Movie.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:
                    continue
    return  HttpResponse('全部电影元数据已经爬取OK')

def scrawl_comment(request):
    """
    爬取所有的电影元数据
    :param request:
    :return:
    """
    return  HttpResponse('全部电影评论已经爬取OK')






@check_login
def tuijian(request):

    uid = int(request.COOKIES.get('uid', -1))
    if uid != -1:
        username = User.objects.filter(id=uid)[0].name

    train = dict()
    history = Like.objects.all()  # 0.1
    for item in history:
        if item.uid_id not in train.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) + 10
    history = See.objects.all()  # 0.1
    for item in history:
        if item.uid_id not in train.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("协同过滤异常啦")
        pass
    if len(newlist) == 0:
        msg = "你还没有在该网站有过评论、浏览行为,请去浏览吧!"
        newlist = Movie.objects.order_by('-id')[:10].values()
    else:
        msg = ""
    #
    tmp = []
    print(newlist)
    for item in newlist:

        try:
            id = item["id"]
        except:
            id = item.id

        if Like.objects.filter(uid_id=uid, hid_id=id):
            is_like = 1
        else:
            is_like = 0
        try:

            item['is_like'] = is_like
        except:
            item.is_like = is_like
        tmp.append(item)
    newlist = tmp
    return render(request, 'tuijian.html', locals())


def test(request):
    return HttpResponse('测试完成')


@check_login
def search(request):
    uid = int(request.COOKIES.get('uid', -1))
    if uid != -1:
        username = User.objects.filter(id=uid)[0].name
    newlist = []
    if request.method == 'POST':
        keywords = request.POST.get('keywords')
        newlist = Movie.objects.filter(title__contains=keywords).values()
        tmp = []
        for item in newlist:
            if Like.objects.filter(uid_id=uid, hid_id=item['id']):
                is_like = 1
            else:
                is_like = 0
            item['is_like'] = is_like
            tmp.append(item)
        newlist = tmp
    else:
        keywords = ''
    return render(request, 'search.html', locals())


def login(request):
    if request.method == "POST":
        tel, pwd = request.POST.get('tel'), request.POST.get('pwd')
        if User.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)
            return obj
        else:
            msg = "用户信息错误,请重新输入!!"
            return render(request, 'login.html', locals())
    else:
        return render(request, 'login.html', locals())


def register(request):
    if request.method == "POST":
        name, tel, pwd = request.POST.get('name'), request.POST.get('tel'), request.POST.get('pwd')
        print(name, tel, pwd)
        if User.objects.filter(tel=tel):
            msg = "你已经有账号了,请登录"
        else:
            User.objects.create(name=name, tel=tel, password=pwd)
            msg = "注册成功,请登录!"
        return render(request, 'login.html', locals())
    else:
        msg = ""
        return render(request, 'register.html', locals())


def logout(request):
    obj = redirect('/')
    obj.delete_cookie('uid')
    return obj

def plot(request):
    raw_data = Movie.objects.all()
    # 1  每个国家 电影排行榜
    main1 = raw_data.values('regions').annotate(count=Count('regions')).order_by('-count')[:10]
    main1_x = [item['regions'] for item in main1]
    main1_y = [item['count'] for item in main1]

    # 2  每年电影排行
    year_list = list(range(1999,2020))
    main2_x = year_list
    main2_y = []
    for year in year_list:
        main2_y.append(raw_data.filter(releaseDate__year=year).count())
    # print(main1)

    # 3  类别被购买前十
    tmp = [item.actors for item in raw_data]
    result_list = []
    for item in tmp:
        result_list = result_list + item.split(',')

    result_dict = {k: result_list.count(k) for k in result_list}
    result_dict = sorted(result_dict.items(), key=lambda x: x[1], reverse=True)  # 最大到最小
    print(result_dict)
    main3 = [{'value': item[1], 'name': item[0]}
             for item in result_dict
             ]
  

    tmp = [item.kind for item in raw_data]
    result_list = []
    for item in tmp:
        result_list = result_list + item.split(',')

    result_dict = {k: result_list.count(k)  for k in result_list}
    result_dict = sorted(result_dict.items(),key=lambda x:x[1],reverse=True)[:5] # 最大到最小
    print(result_dict)
    main4 = [{'value': item[1],'name': item[0]}
        for item in result_dict
    ]
    main4_x = [item['name'] for item in main4]

    return render(request,'plot.html',locals())




5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅

感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐