计算机毕业设计Python深度学习动漫推荐系统 动漫视频推荐系统 机器学习 协同过滤推荐算法 bilibili动漫爬虫 数据可视化 数据分析 大数据毕业设计 混合神经网络推荐算法 SVD 卷积神经网络

本推荐系统采用的是分层模型设计思想,第一层为前端页面模型设计,注重为实现页面的展示效果,主用的编程语言为JavaScript,和前端主流框架bootstrap。
第二层为后端模型设计,编程语言选了简单易懂的python,用Django作为后端框架进行开发,此框架是python web系统开发的首选框架,简单易用。
第三层为算法的设计与实现的逻辑,用协同过滤算法来实现,第四层为数据库表的设计,用SQLite数据库。
本系统web端的功能模块,主要实现动漫显示、动漫分类显示、热门动漫排序显示、收藏动漫排序显示、时间排序显示、评分排序显示、算法推荐、动漫搜索、动漫信息管理等功能,并进行数据库的详细设计,完成设计阶段的各项功能,并对此系统进行功能测试,最后,系统进行相关的实际应用操作,通过系统的使用,用户进入动漫推荐系统,此系统可以根据用户对动漫所打的标签行为,给用户推荐用户所感兴趣的动漫,准确率在百分之75左右,用户可以查看信息,观看动漫,给动漫评分等操作,本系统基本上完成了预期的基本功能。

该推荐系统基于协同过滤算法实现,采用了分层模型设计思想,并使用了多种技术栈进行开发。

技术栈:
1. 前端页面模型设计:JavaScript和前端主流框架bootstrap,用于实现页面的展示效果。
2. 后端模型设计:Python作为编程语言,Django作为后端框架进行开发。Django是一个简单易用的Python web开发框架。
3. 算法设计与实现逻辑:采用协同过滤算法来实现推荐功能。
4. 数据库表设计:使用SQLite数据库进行数据存储。

实现步骤:
1. 前端页面模型设计:使用JavaScript和bootstrap框架搭建用户界面,实现动漫显示、分类显示、排序显示等功能。
2. 后端模型设计:使用Django框架搭建后端服务器,处理前端请求,调用相应的算法进行推荐计算,并将结果返回给前端页面。
3. 算法设计与实现逻辑:采用协同过滤算法来实现推荐功能。具体步骤包括:
   - 初始化数据:获取用户的浏览行为数据。
   - 计算两个用户的皮尔逊相关系数:通过遍历整个数据集,计算用户之间的相似度。
   - 寻找最相似的用户:根据用户之间的相似度,找到与当前用户最相似的N个用户。
   - 推荐动漫给用户:根据最相似的用户的浏览行为,推荐动漫给当前用户。
4. 数据库表设计:使用SQLite数据库进行数据存储,包括用户信息、动漫信息、用户对动漫的评分等。

通过以上步骤,该推荐系统实现了基于用户和基于物品的推荐功能,根据用户的标签行为和评分情况,给用户推荐其感兴趣的动漫。系统具有良好的用户界面和高准确率的推荐效果,用户可以方便地查看动漫信息、观看动漫、给动漫评分等操作。整个系统的开发过程经过详细的设计和功能测试,并成功应用于实际场景中。

项目目录结构:
    |-- comic_data.py  # 动漫数据抓取模块
    |-- db.sqlite3  # SQLite数据库文件
    |-- manage.py  # Django管理命令入口
    |-- movie
    |   |-- __init__.py  # 模块初始化文件
    |   |-- admin.py  # Django后台管理配置文件
    |   |-- apps.py  # Django应用配置文件
    |   |-- data.py  # 动漫数据处理模块
    |   |-- forms.py  # 表单定义文件
    |   |-- migrations  # 数据库迁移文件夹
    |   |-- models.py  # 数据库模型定义文件
    |   |-- serializers.py  # 序列化器定义文件
    |   |-- templatetags  # 模板标签文件夹
    |   |   |-- __init__.py
    |   |   |-- grav_tag.py  # 自定义模板标签:用于生成星级评分显示
    |   |   |-- is_like.py  # 自定义模板标签:用于判断用户是否喜欢某部动漫
    |   |   `-- list_slice.py  # 自定义模板标签:用于切片列表
    |   |-- tests.py  # 测试文件
    |   `-- views.py  # 视图函数定义文件
    |-- movie.sql  # 动漫数据的SQL文件
    |-- movie_it
    |   |-- cache_keys.py  # 缓存键定义文件
    |   |-- data.json  # 数据JSON文件
    |   |-- douban_crawler.py  # 豆瓣爬虫模块
    |   |-- play_2.py  # 播放模块
    |   |-- populate_movies_script.py  # 动漫数据填充脚本
    |   `-- recommend_movies.py  # 推荐动漫模块
    |-- movierecomend
    |   |-- __init__.py  # 模块初始化文件
    |   |-- settings.py  # Django项目配置文件
    |   |-- templatetags  # 模板标签文件夹
    |   |   |-- __init__.py
    |   |   |-- grav_tag.py  # 自定义模板标签:用于生成星级评分显示
    |   |   `-- list_slice.py  # 自定义模板标签:用于切片列表
    |   |-- urls.py  # URL配置文件
    |   `-- wsgi.py  # WSGI应用程序入口
    |-- readme.txt  # 项目说明文档
    |-- requirements.txt  # 项目依赖库列表
    |-- static  # 静态文件目录
    |   |-- css  # CSS文件
    |   |-- images  # 图片文件
    |   `-- js  # JavaScript文件
    |-- templates  # 模板文件目录
    |   |-- all_tags.html  # 显示所有标签的页面模板
    |   |-- base.html  # 基础模板
    |   |-- base_show.html  # 基础展示模板
    |   |-- choose_tag.html  # 选择标签的页面模板
    |   |-- items.html  # 动漫列表展示页面模板
    |   |-- login.html  # 登录页面模板
    |   |-- movie.html  # 单个动漫展示页面模板
    |   |-- my_comment.html  # 我的评论页面模板
    |   |-- my_rate.html  # 我的评分页面模板
    |   |-- mycollect.html  # 我的收藏页面模板
    |   |-- personal.html  # 个人信息页面模板
    |   |-- register.html  # 注册页面模板
    |   |-- results.html  # 搜索结果页面模板
    |   `-- tag_movie.html  # 标签对应动漫页面模板
 

核心算法代码分享如下:

import asyncio
import logging

import aiohttp
from bs4 import BeautifulSoup
from crawler_utils.utils import timer

base_url = 'https://movie.douban.com/top250'
results = {}
new_url = 'https://www.douban.com/doulist/30299/?start=0&sort=seq&playable=0&sub_type='
ids = 0

tasks = []


class Movie:
    def __init__(self, id, title, description, star, leader, tags, years, country, director_description, image_link):
        self.id = id
        self.star = star
        self.description = description
        self.title = title
        self.leader = leader
        self.tags = tags
        self.years = years
        self.country = country
        self.director_description = director_description
        self.image_link = image_link


async def fetch(url):
    async with aiohttp.ClientSession()as session:
        async with session.get(url) as response:
            print(response.status)
            assert response.status == 200
            return await response.text()


async def write_images(image_link, image_name):
    print('write images....', image_link)
    async with aiohttp.ClientSession()as session:
        async with session.get(image_link) as response:
            assert response.status == 200
            with open('movie_images/' + image_name + '.png', 'wb')as opener:
                while True:
                    chunk = await response.content.read(1024)
                    if not chunk:
                        break
                    opener.write(chunk)


async def parse_list(html):
    soup = BeautifulSoup(html, 'html.parser')
    movies = soup.find_all('div', {'class': 'doulist-item'})
    movie_list = []

    for movie in movies:
        try:
            title = movie.find('div', {'class': 'title'}).text.strip().replace('/', '_')
        except Exception as e:
            print(movie)
            print(e)
            continue
        try:
            image_link = movie.find('div', {'class': 'post'}).find('img')
            if image_link is None:
                continue
            else:
                image_link = image_link['src']
                await write_images(image_link, title)
            rate = movie.find('div', {'class': 'rating'})
            dou_rate = rate.find('span', {'class': 'rating_nums'})
            if dou_rate is None:
                dou_rate = '0'
            else:
                dou_rate = dou_rate.text
            # rate_num = rate.find_all('span')[-1].text
            abstract = movie.find('div', {'class': 'abstract'}).text.strip().split('\n')
            tags = country = leader = year = director_ = ''
            for ab in abstract:
                if len(ab.strip()) == 0:
                    continue
                ab_list = ab.split(':')
                key = ab_list[0].strip()
                value = ab_list[1].strip()
                if key == '导演':
                    director_ = value
                elif key == '主演':
                    leader = value
                elif key == '年份':
                    year = value
                elif key == '制片国家/地区':
                    country = value
                elif key == '类型':
                    tags = value
        except Exception as e:
            print(movie)
            raise e
        global ids
        ids += 1
        movie_list.append(Movie(image_link=image_link, title=title, star=dou_rate, leader=leader, tags=tags, country=country, director_description=director_, years=year, id=ids, description=''))
    new_link = soup.find('span', {'class': 'next'})
    if new_link is not None:
        try:
            new_link = new_link.a['href']
        except Exception:
            new_link = None
    return movie_list, new_link


async def parse_250(html):
    soup = BeautifulSoup(html, 'html.parser')
    movies_info = soup.find('ol', {'class': 'grid_view'})
    movies = []
    for movie_info in movies_info.find_all('li'):
        pic = movie_info.find('div', {'class': 'pic'})
        picture_url = pic.find('img').attrs['src']
        movie_id = pic.find('em').text
        url = movie_info.find('div', {"class": "info"})
        title = url.find('span', {'class': 'title'}).text
        # 保存图片文件到本地
        print('write image ', picture_url)
        await write_images(picture_url, title)
        info = url.find('div', {'class': 'bd'})
        movie_detail = info.find('p')
        quote = info.find('p', {'class': 'quote'})
        if quote is not None:
            description = quote.find('span').text
        else:
            description = ''
            print(title + 'description is None')
        star = info.find('div', {"class": 'star'}).find('span', {'class': 'rating_num'}).text
        tags = movie_detail.text.strip().split('\n')[-1].split('/')[-1].split(' ')
        tags = [tag.strip() for tag in tags]
        years = movie_detail.text.strip().split('\n')[-1].split('/')[0].strip()
        country = movie_detail.text.strip().split('\n')[-1].split('/')[1].strip()
        temp = movie_detail.text.strip().split('\n')
        try:
            director_description = temp[0].split('/')[0].strip().split('\xa0')[0].split(':')[1]
        except IndexError:
            director_description = ''
        try:
            leader = temp[0].split('/')[0].strip().split('\xa0')[-1].split(':')[1]
        except IndexError:
            leader = ''
        assert title is not None
        assert star is not None
        assert leader is not None
        assert years is not None
        assert country is not None
        assert director_description is not None
        assert tags is not None
        assert picture_url is not None
        assert movie_id is not None
        movies.append(Movie(title=title, description=description, star=star, leader=leader, years=years, country=country, director_description=director_description, tags=tags, image_link=picture_url,
                            id=movie_id
                            )
                      )
    next_page = soup.find('link', {'rel': 'next'})
    if next_page is not None and next_page.attrs.get('href'):
        next_link = base_url + next_page.attrs['href']
    else:
        print('finished!')
        next_link = None
    return movies, next_link


def write_movies(movies):
    print('write movies..')
    with open('movies_2.csv', 'a+')as opener:
        if opener.tell() == 0:
            opener.writelines(','.join(['id', 'title ', 'image_link ', 'country ', 'years ', 'director_description', 'leader', 'star ', 'description', 'tags', '\n']))
        for movie in movies:
            opener.write(','.join([str(movie.id), movie.title, movie.image_link, movie.country, movie.years, movie.director_description, movie.leader, movie.star, movie.description, '/'.join(movie.tags), '\n']))


async def get_results(url, parser):
    html = await fetch(url)
    movies, next_link = await parser(html)
    write_movies(movies)
    return next_link
    # results[url] = movie


async def handle_tasks(work_queue, parser):
    while not work_queue.empty():
        current_url = await work_queue.get()
        try:
            next_link = await get_results(current_url, parser)
            print('put link:', next_link)
            if next_link is not None:
                work_queue.put_nowait(next_link)

        except Exception as e:
            logging.exception('Error for {}'.format(current_url), exc_info=True)


@timer
def envent_loop():
    q = asyncio.Queue()
    q.put_nowait(new_url)
    loop = asyncio.get_event_loop()
    tasks.append(handle_tasks(q, parse_list))
    loop.run_until_complete(asyncio.wait(tasks))


envent_loop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

B站计算机毕业设计1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值