💗博主介绍:✌全网粉丝15W+,CSDN全栈领域优质创作者,博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战,以及程序定制化开发、文档编写、答疑辅导等。
👇🏻 精彩专栏 推荐订阅👇🏻
计算机毕业设计精品项目案例(持续更新)
🌟文末获取源码+数据库+文档🌟
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以和学长沟通,希望帮助更多的人
一.前言
在当今多媒体时代,网络电视剧已成为主流娱乐方式之一。随着互联网的普及和在线视频平台的迅猛发展,观众逐渐从传统电视转向网络平台观看电视剧。这一转变不仅改变了人们的观影习惯,也对电视剧内容制作、发布及评价体系带来了深远影响。在这样的背景下,如何准确评估一部网络电视剧的受欢迎程度,把握观众偏好,并据此指导内容创新与精准营销,成为行业急需解决的问题。数据科学的发展为这一问题提供了新的解决思路。基于大数据的网络电视剧收视率分析系统正是在这样的需求推动下应运而生的。大数据作为构建在Hadoop之上的数据仓库解决方案,能够处理PB级别的大数据,并提供高效的SQL查询功能,非常适合用来进行海量收视数据的存储与分析。
基于大数据的网络电视剧收视率分析系统对于电视剧制作方、发行方以及广告商等都有着极其重要的意义。对制作方而言,通过系统提供的精确收视数据可以了解观众喜好,指导剧本创作和剧集改进,提高作品质量;对发行方来说,可以基于收视趋势调整发行策略,优化推广计划,扩大观众群体;广告商则能利用这些数据分析观众特征,实现广告精准投放,提升广告效果。对观众而言,系统的交流论坛提供了一个分享观点、参与讨论的平台,增强了观众之间的互动,丰富了观影体验。整个系统不仅推动了电视剧市场的数据分析技术进步,也为网络时代的影视文化消费行为研究提供了实证基础,具有广泛的社会和经济效益。
该网络电视剧收视率分析系统采用B/S架构、开发语言使用Java语言,并采用Hadoop技术、Scrapy爬虫技术以及 springboot框架进行开发。介绍网络爬虫的基本原理,Java及Python开发环境的搭建,PyCharm scrapy模块的爬虫数据的运用,把获取到的数据进行清洗、整合,储存数据到MySQL,然后进行Echart数据可视化的呈现,简单对呈现的图进行数据分析。通过利用大数据的大数据处理能力,该系统能够存储和分析海量的收视数据,从而揭示不同电视剧的受欢迎程度和观众偏好。管理员可以通过系统管理模块轻松地更新用户信息、发布公告以及维护系统稳定。用户得以在个人中心内修改密码、管理发布内容和收藏喜好。该系统还提供了一个交流论坛,以增强用户间的互动和讨论。
二.技术环境
开发语言:Java+Python
Java框架:SpringBoot
数据库:mysql 5.7或更高版本
数据库工具:Navicat11
爬虫框架:Scrapy
大数据框架:Hadoop
开发软件:Idea/Eclipse
前端框架:vue.js
三.功能设计
本课题要求实现一套网络电视剧收视率分析系统,系统主要包括管理员和用户两大功能模块。
(1)管理员用例图如下所示:
(2)用户用例图如下所示:
系统功能结构图是系统设计阶段,系统功能结构图只是这个阶段一个基础,整个系统的架构决定了系统的整体模式,是系统的根据。本系统的整个设计结构如图所示。
四.数据设计
概念模型的设计是为了抽象真实世界的信息,并对信息世界进行建模。它是数据库设计的强大工具。数据库概念模型设计可以通过E-R图描述现实世界的概念模型。ER图是由实体及其关系构成的图,通过E/R图可以清楚地描述系统涉及到的实体之间的相互关系。在系统中对一些主要的几个关键实体如图:以下将“用户、收视率、交流论坛、公告信息”等作为实体,它们的局部E-R如图所示:
五.部分效果展示
前台用户功能实现效果
当人们打开系统的网址后,首先看到的就是首页界面。在这里,人们能够看到系统的导航条,通过导航条导航进入各功能展示页面进行操作。系统首页界面如图所示:
收视率:在收视率页面可以查看到时间段、排名、播出集数、收视率、收视份额、播出频道、点击次数等详细信息,并根据需要进行评论或收藏操作;收视率页面如图所示:
个人中心:在个人中心页面可以进行个人信息修改、修改密码、我的发布、我的收藏等详细操作;如图所示:
后台管理员功能实现效果
在登录流程中,用户首先在Vue前端界面输入用户名和密码。这些信息通过HTTP请求发送到Java后端。后端接收请求,通过与MySQL数据库交互验证用户凭证。如果认证成功,后端会返回给前端,允许用户访问系统。这个过程涵盖了从用户输入到系统验证和响应的全过程。如图所示:
在这里插入图片描述
管理员进入主页面,主要功能包括对用户、收视率、公告信息、交流论坛、系统管理、我的信息等进行操作。
用户功能在视图层(view层)进行交互,比如点击“查询、添加或删除”按钮或填写用户信息表单。这些用户表单动作被视图层捕获并作为请求发送给相应的控制器层(controller层)。控制器接收到这些请求后,调用服务层(service层)以执行相关的业务逻辑,例如验证输入数据的有效性和与数据库的交互。服务层处理完这些逻辑后,进一步与数据访问对象层(DAO层)交互,后者负责具体的数据操作如查看、修改或删除用户信息,并将操作结果返回给控制器。最终,控制器根据这些结果更新视图层,以便用户功能可以看到最新的信息或相应的操作反馈。如图5-7所示:
收视率功能在视图层(view层)进行交互,比如点击“删除、爬取数据、生成数据”按钮或填写收视率信息表单。这些收视率表单动作被视图层捕获并作为请求发送给相应的控制器层(controller层)。控制器接收到这些请求后,调用服务层(service层)以执行相关的业务逻辑,例如验证输入数据的有效性和与数据库的交互。服务层处理完这些逻辑后,进一步与数据访问对象层(DAO层)交互,后者负责具体的数据操作如查看、修改、查看评论或删除收视率信息,并将操作结果返回给控制器。最终,控制器根据这些结果更新视图层,以便收视率功能可以看到最新的信息或相应的操作反馈。如图5-8所示:
管理员点击交流论坛,在交流论坛页面输入标题进行查询、添加或删除交流论坛列表,并根据需要对交流论坛详细信息进行查看、修改或删除操作。如图所示:
公告信息功能在视图层(view层)进行交互,比如点击“查询、添加或删除”按钮或填写公告信息表单。这些公告信息表单动作被视图层捕获并作为请求发送给相应的控制器层(controller层)。控制器接收到这些请求后,调用服务层(service层)以执行相关的业务逻辑,例如验证输入数据的有效性和与数据库的交互。服务层处理完这些逻辑后,进一步与数据访问对象层(DAO层)交互,后者负责具体的数据操作如查看、修改或删除公告信息,并将操作结果返回给控制器。最终,控制器根据这些结果更新视图层,以便公告信息功能可以看到最新的信息或相应的操作反馈。如图所示
数据可视化分析大屏展示实现效果
管理员进行爬取数据后可以在看板页面查看到系统简介、剧名、播出频道、排名、用户人数、收视率、收拾份额、用户总数、收视率总数、收视率详情等实时的分析图进行可视化管理;看板大屏选择了Echart作为数据可视化工具,它是一个使用JavaScript实现的开源可视化库,能够无缝集成到Java Web应用中。Echart的强大之处在于其丰富的图表类型和高度的定制化能力,使得管理人员可以通过直观的图表清晰地把握网络电视剧的各项运营数据。
为了实现对网络电视剧信息的自动化收集和更新,我们采用了Apache Spark作为爬虫技术的基础。Spark的分布式计算能力使得系统能够高效地处理大规模数据,无论是从互联网上抓取最新的网络电视剧信息,还是对内部数据进行ETL(提取、转换、加载)操作,都能够保证数据的实时性和准确性。
在大数据分析方面,系统采用了Hadoop框架。Hadoop是一个能够处理大数据集的分布式存储和计算平台,它的核心是HDFS(Hadoop Distributed File System)和MapReduce计算模型。通过Hadoop,我们可以对收集到的大量数据进行存储和分析。看板页面如图5-9所示:
六.部分功能代码
# # -*- coding: utf-8 -*-# 数据爬取文件import scrapy
import pymysql
import pymssql
from..items import ShoushilvItem
import time
from datetime import datetime,timedelta
import datetime as formattime
import re
import random
import platform
import json
import os
import urllib
from urllib.parse import urlparse
import requests
import emoji
import numpy as np
import pandas as pd
from sqlalchemy import create_engine
from selenium.webdriver import ChromeOptions, ActionChains
from scrapy.http import TextResponse
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
# 收视率classShoushilvSpider(scrapy.Spider):
name ='shoushilvSpider'
spiderUrl ='http://www.cavbd.cn/ranking/weekly/20240309-20240315.html'
start_urls = spiderUrl.split(";")
protocol =''
hostname =''
realtime =Falsedef__init__(self,realtime=False,*args,**kwargs):super().__init__(*args,**kwargs)
self.realtime = realtime=='true'defstart_requests(self):
plat = platform.system().lower()ifnot self.realtime and(plat =='linux'or plat =='windows'):
connect = self.db_connect()
cursor = connect.cursor()if self.table_exists(cursor,'727702cu_shoushilv')==1:
cursor.close()
connect.close()
self.temp_data()return
pageNum =1+1for url in self.start_urls:if'{}'in url:for page inrange(1, pageNum):
next_link = url.format(page)yield scrapy.Request(
url=next_link,
callback=self.parse
)else:yield scrapy.Request(
url=url,
callback=self.parse
)# 列表解析defparse(self, response):
_url = urlparse(self.spiderUrl)
self.protocol = _url.scheme
self.hostname = _url.netloc
plat = platform.system().lower()ifnot self.realtime and(plat =='linux'or plat =='windows'):
connect = self.db_connect()
cursor = connect.cursor()if self.table_exists(cursor,'727702cu_shoushilv')==1:
cursor.close()
connect.close()
self.temp_data()returnlist= response.css('div.table table tbody tr')for item inlist:
fields = ShoushilvItem()if'(.*?)'in'''div[class="years yearOp"] span.selectedColor::text''':try:
fields["sjd"]=str( re.findall(r'''div[class="years yearOp"] span.selectedColor::text''', item.extract(), re.DOTALL)[0].strip()+response.css('''div[class="date dateOp"] span.selectedColor::text''').extract_first())except:passelse:try:
fields["sjd"]=str( self.remove_html(item.css('''div[class="years yearOp"] span.selectedColor::text''').extract_first())+response.css('''div[class="date dateOp"] span.selectedColor::text''').extract_first())except:passif'(.*?)'in'''td:nth-child(1)::text''':try:
fields["ranking"]=int( re.findall(r'''td:nth-child(1)::text''', item.extract(), re.DOTALL)[0].strip())except:passelse:try:
fields["ranking"]=int( self.remove_html(item.css('td:nth-child(1)::text').extract_first()))except:passif'(.*?)'in'''td:nth-child(2)::text''':try:
fields["juming"]=str( re.findall(r'''td:nth-child(2)::text''', item.extract(), re.DOTALL)[0].strip())except:passelse:try:
fields["juming"]=str( self.remove_html(item.css('''td:nth-child(2)::text''').extract_first()))except:passif'(.*?)'in'''td:nth-child(3)::text''':try:
fields["bcjs"]=str( re.findall(r'''td:nth-child(3)::text''', item.extract(), re.DOTALL)[0].strip())except:passelse:try:
fields["bcjs"]=str( self.remove_html(item.css('''td:nth-child(3)::text''').extract_first()))except:passif'(.*?)'in'''td:nth-child(4)::text''':try:
fields["shousl"]=float( re.findall(r'''td:nth-child(4)::text''', item.extract(), re.DOTALL)[0].strip().replace('%',''))except:passelse:try:
fields["shousl"]=float( self.remove_html(item.css('td:nth-child(4)::text').extract_first()).replace('%',''))except:passif'(.*?)'in'''td:nth-child(5)::text''':try:
fields["ssfe"]=float( re.findall(r'''td:nth-child(5)::text''', item.extract(), re.DOTALL)[0].strip().replace('%',''))except:passelse:try:
fields["ssfe"]=float( self.remove_html(item.css('td:nth-child(5)::text').extract_first()).replace('%',''))except:passif'(.*?)'in'''td:nth-child(6)::text''':try:
fields["bcpd"]=str( re.findall(r'''td:nth-child(6)::text''', item.extract(), re.DOTALL)[0].strip())except:passelse:try:
fields["bcpd"]=str( self.remove_html(item.css('''td:nth-child(6)::text''').extract_first()))except:passyield fields
# 数据清洗defpandas_filter(self):
engine = create_engine('mysql+pymysql://root:123456@localhost/spider727702cu?charset=UTF8MB4')
df = pd.read_sql('select * from shoushilv limit 50', con = engine)# 重复数据过滤
df.duplicated()
df.drop_duplicates()#空数据过滤
df.isnull()
df.dropna()# 填充空数据
df.fillna(value ='暂无')# 异常值过滤# 滤出 大于800 和 小于 100 的
a = np.random.randint(0,1000, size =200)
cond =(a<=800)&(a>=100)
a[cond]# 过滤正态分布的异常值
b = np.random.randn(100000)# 3σ过滤异常值,σ即是标准差
cond = np.abs(b)>3*1
b[cond]# 正态分布数据
df2 = pd.DataFrame(data = np.random.randn(10000,3))# 3σ过滤异常值,σ即是标准差
cond =(df2 >3*df2.std()).any(axis =1)# 不满⾜条件的⾏索引
index = df2[cond].index
# 根据⾏索引,进⾏数据删除
df2.drop(labels=index,axis =0)# 去除多余html标签defremove_html(self, html):if html ==None:return''
pattern = re.compile(r'<[^>]+>', re.S)return pattern.sub('', html).strip()# 数据库连接defdb_connect(self):type= self.settings.get('TYPE','mysql')
host = self.settings.get('HOST','localhost')
port =int(self.settings.get('PORT',3306))
user = self.settings.get('USER','root')
password = self.settings.get('PASSWORD','123456')try:
database = self.databaseName
except:
database = self.settings.get('DATABASE','')iftype=='mysql':
connect = pymysql.connect(host=host, port=port, db=database, user=user, passwd=password, charset='utf8')else:
connect = pymssql.connect(host=host, user=user, password=password, database=database)return connect
# 断表是否存在deftable_exists(self, cursor, table_name):
cursor.execute("show tables;")
tables =[cursor.fetchall()]
table_list = re.findall('(\'.*?\')',str(tables))
table_list =[re.sub("'",'',each)for each in table_list]if table_name in table_list:return1else:return0# 数据缓存源deftemp_data(self):
connect = self.db_connect()
cursor = connect.cursor()
sql ='''
insert into `shoushilv`(
id
,sjd
,ranking
,juming
,bcjs
,shousl
,ssfe
,bcpd
)
select
id
,sjd
,ranking
,juming
,bcjs
,shousl
,ssfe
,bcpd
from `727702cu_shoushilv`
where(not exists (select
id
,sjd
,ranking
,juming
,bcjs
,shousl
,ssfe
,bcpd
from `shoushilv` where
`shoushilv`.id=`727702cu_shoushilv`.id
))
order by rand()
limit 50;
'''
cursor.execute(sql)
connect.commit()
connect.close()
源码及文档获取
文章下方名片联系我即可~
大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻
精彩专栏推荐订阅:在下方专栏👇🏻
最新计算机毕业设计选题篇-选题推荐
小程序毕业设计精品项目案例-200套
Java毕业设计精品项目案例-200套
Python毕业设计精品项目案例-200套
大数据毕业设计精品项目案例-200套
💟💟如果大家有任何疑虑,欢迎在下方位置详细交流。
版权归原作者 一点毕设 所有, 如有侵权,请联系我们删除。