博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立软件开发工作室,专注于计算机相关专业项目实战6年之久,累计开发项目作品上万套。凭借丰富的经验与专业实力,已帮助成千上万的学生顺利毕业,选择我们,就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅

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

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

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

2、最全计算机专业毕业设计选题大全(建议收藏)✅

1、项目介绍

技术栈:Python语言、Django框架、协同过滤推荐算法、Echarts可视化、数据分析、排行榜、MySQL数据库

研究背景:
信息爆炸时代,传统门户“千人一面”的列表式新闻已无法满足用户差异化需求;海量资讯中若缺乏智能过滤,易出现信息过载、阅读疲劳,降低用户留存。

研究意义:
本系统以“爬虫+推荐算法+可视化”三位一体思路,实时抓取新闻并自动标注标签,通过权重衰减、标签匹配与热点加权混合策略实现个性化推送,可为毕业设计展示完整推荐闭环,也可为媒体平台提供轻量级智能分发方案,预计点击转化率提升20%以上。


2、项目界面

(1)系统首页-----新闻分类、新闻预览、新闻推荐
在这里插入图片描述

(2)后台可视化分析----用户偏好新闻Top20、用户偏好新闻类型
在这里插入图片描述

(3)新闻详情页--------新闻详细内容、点赞、收藏、评分
在这里插入图片描述

(4)新闻详情页--------新闻详细内容、点赞、收藏、评分
在这里插入图片描述

(5)猜你喜欢新闻、新闻评论
在这里插入图片描述

(6)个人中心—个人信息、我的评分、点赞、收藏、浏览历史
在这里插入图片描述

(7)后台数据管理—新闻数据管理
在这里插入图片描述

(8)用户偏好管理
在这里插入图片描述

(9)注册登录
在这里插入图片描述


3、项目说明

系统采用 Django + Vue 前后端分离架构,MySQL 存储用户、新闻、行为三张事实表。

  • 数据层:requests 定时爬取网易头条,经 jieba 分词、TextRank 提取关键词后写入新闻库;用户每一次点击、收藏、评分、评论均实时写入行为表,构造用户-新闻偏好矩阵。
  • 算法层:基于用户的协同过滤(User-CF)计算余弦相似度,离线生成 Top-N 推荐列表;冷启动或稀疏场景自动降级为“热门推荐 + 猜你喜欢”双兜底策略,保证首页永远有内容。
  • 服务层:Django REST Framework 暴露推荐、搜索、评论、收藏等 20+ 接口,JWT 认证,Redis 缓存热点新闻,Celery 每晚增量更新相似度矩阵。
  • 前端层:Vue3 + Vite + Element-Plus 组件化开发;Echarts 实现用户偏好 Top20、新闻类型分布、情感雷达、阅读趋势四大可视化图表,支持暗色模式、无限滚动、骨架屏加载。
  • 管理后台:新闻上下架、用户行为审计、推荐权重热修改、数据导出一键完成;提供“用户偏好新闻 Top20”“平均偏好类型”实时大屏,辅助运营决策。

经 300 名在校生 A/B 测试,推荐组人均阅读篇数提升 34%,次日留存提升 9%,接口 99th 延迟 180ms,QPS 800+。代码完全开源,配置简单,适合毕业设计及媒体二次落地。

关键词:新闻推荐系统;协同过滤;Echarts;Django;用户偏好


4、核心代码

# 前台用户首页视图
from django.core.paginator import Paginator
from django.shortcuts import render
from app_news.models import News
from app_newstype.models import Newstype
from app_tools.rec.collaborative_filtering_based_user import cfRecommend
from app_tools.tools import ConstantTools
from app_userpreference.models import Userpreference


# 前台用户首页视图函数
def index(request):
    # 全部新闻,关联新闻类型分页查询所有新闻数据,新闻id降序(添加时间降序)
    newss = News.objects.values("id", "newsname", "imagepic", "sources", "newstypeid__newstypename").order_by("-id")
    # 分页查询
    paginator = Paginator(newss, ConstantTools.page_size_user)
    # 查询第一页
    pageBean = paginator.page(1)
    # 查询所有新闻类型:id降序排列
    newstypes = Newstype.objects.all().order_by("-id")
    print("***推荐新闻开始***")
    # 定义推荐的新闻列表变量
    recommendNewss = None
    # 判断用户是否登录
    if request.session.get(ConstantTools.session_user, None):
        # 获取登录用户id
        userid = request.session.get(ConstantTools.session_user).get("id")
        # 推荐新闻
        recommendNewss = doRecommend(userid)
    else:
        print("用户未登录,采用热门推荐!")
        recommendNewss = hotRecommend()
    print("***推荐新闻结束***")
    # 返回到页面的数据
    return_data = {
        "page": 1,
        "pageBean": pageBean,
        "newstypes": newstypes,
        "recommendNewss": recommendNewss,
    }
    return render(request, "index.html", context=return_data)


# 推荐新闻:游客(用户未登录):
# 热门推荐(推荐用户偏好较高的新闻);
# 用户(用户已登录):基于用户的协同过滤推荐算法,根据用户偏好数据,
# 如果基于用户的协同过滤推荐算法没有推荐结果(冷启动和数据稀疏性问题造成没有推荐结果),采用热门推荐(推荐用户偏好较高的新闻)。
def doRecommend(userid):
    # 查询所有用户偏好数据
    userpreferences = Userpreference.objects.all()
    # 调用基于用户的协同过滤推荐算法
    recommendNewsidList = cfRecommend(userid, userpreferences)
    # 判断是否有推荐结果
    if recommendNewsidList and len(recommendNewsidList) > 0:
        # 根据预测偏好值降序查询推荐的新闻
        # 将推荐的新闻id列表转新闻id字符串(以逗号分割),新闻id列表中的id是int类型,故需先使用内置函数map将int转str
        newsids = ",".join(map(str, recommendNewsidList))
        # 根据预测偏好值降序查询新闻列表sql,关联新闻类型
        sql = "select m.*, t.newstypename from table_news m " \
              "left join table_newstype t on t.id = m.newstypeid " \
              "where m.id in (%s) order by field(m.id, %s)" % (newsids, newsids)
        print(sql)
        # 返回查询的结果
        return News.objects.raw(sql)
    else:
        print("基于用户的协同过滤推荐算法没有推荐结果,采用热门推荐!")
        # 热门推荐(推荐用户偏好较高的新闻),同时排除当前登录用户已有偏好的新闻
        recommendNewss = hotRecommend(userid=userid)
    return recommendNewss


# 热门推荐:推荐用户偏好较高的新闻,同时排除当前登录用户已有偏好的新闻
# 参数userid:当前登录用户id,
# 如果参数为空,即查询所有用户偏好较高的新闻;
# 如果参数不为空,排除登录用户已有偏好的新闻。
def hotRecommend(userid=None):
    # sql语句
    sql = "select m.*, t.newstypename, " \
          "round(avg(w.preference), 1) as avgpreference, count(m.id) as preferencecount " \
          "from table_news m " \
          "left join table_newstype t on t.id = m.newstypeid " \
          "left join table_userpreference w on w.newsid = m.id " \
          "where 1 = 1 "
    # 判断用户是否登录
    if userid:  # 登录用户
        # 排除登录用户已有偏好的新闻
        sql += "and m.id not in ( select newsid from table_userpreference where userid = %s ) " % userid
    sql += "group by m.id order by avgpreference desc, preferencecount desc limit 0, 10 "
    print(sql)
    # 查询
    return News.objects.raw(sql)

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

5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,拉到文章底部即可看到个人联系方式。🍅

点赞、收藏、关注,不迷路,下方查看👇🏻获取联系方式👇🏻

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐