大数据可视化项目——基于Python豆瓣电影数据可视化分析系统的设计与实现

大数据可视化项目——基于Python豆瓣电影数据可视化分析系统的设计与实现

本项目旨在通过对豆瓣电影数据进行综合分析与可视化展示,构建一个基于Python的大数据可视化系统。通过数据爬取收集、清洗、分析豆瓣电影数据,我们提供了一个全面的电影信息平台,为用户提供深入了解电影产业趋势、影片评价与演员表现的工具。项目的关键步骤包括数据采集、数据清洗、数据分析与可视化展示。首先,我们使用爬虫技术从豆瓣电影网站获取丰富的电影数据,包括电影基本信息、评分、评论等存储到Mysql数据库。然后,通过数据清洗与预处理,确保数据的质量与一致性,以提高后续分析的准确性。数据分析阶段主要包括对电影评分分布、不同类型电影的数量分布、评分、演员的影响力等方面的深入研究。基于Echarts进行可视化展示,借助Python中的数据分析库(如Pandas、NumPy)和可视化库(如Matplotlib、Seaborn),我们能够以图表的形式清晰地展示电影数据的特征和趋势。最终,我们将分析结果以交互式的可视化界面呈现,用户可以通过系统自定义的查询与过滤功能,深入挖掘他们感兴趣的电影信息。这个项目不仅为电影爱好者提供了一个全面的数据参考平台,也为电影产业从业者提供了洞察行业动向的工具。

最后我们爬取到的字段信息:电影名,评分,封面图,详情url,上映时间,导演,类型,制作国家,语言,片长,电影简介,星星比例,多少人评价,预告片,前五条评论,五张详情图片

 for i,moveInfomation in enumerate(moveisInfomation):try:resultData = {}# 详情resultData['detailLink'] = detailUrls[i]# 导演(数组)resultData['directors'] = ','.join(moveInfomation['directors'])# 评分resultData['rate'] = moveInfomation['rate']# 影片名resultData['title'] = moveInfomation['title']# 主演(数组)resultData['casts'] = ','.join(moveInfomation['casts'])# 封面resultData['cover'] = moveInfomation['cover']# =================进入详情页====================detailMovieRes = requests.get(detailUrls[i], headers=headers)soup = BeautifulSoup(detailMovieRes.text, 'lxml')# 上映年份resultData['year'] = re.findall(r'[(](.*?)[)]',soup.find('span', class_='year').get_text())[0]types = soup.find_all('span',property='v:genre')for i,span in enumerate(types):types[i] = span.get_text()# 影片类型(数组)resultData['types'] = ','.join(types)country = soup.find_all('span',class_='pl')[4].next_sibling.strip().split(sep='/')for i,c in enumerate(country):country[i] = c.strip()# 制作国家(数组)resultData['country'] = ','.join(country)lang = soup.find_all('span', class_='pl')[5].next_sibling.strip().split(sep='/')for i, l in enumerate(lang):lang[i] = l.strip()# 影片语言(数组)resultData['lang'] = ','.join(lang)upTimes = soup.find_all('span',property='v:initialReleaseDate')upTimesStr = ''for i in upTimes:upTimesStr = upTimesStr + i.get_text()upTime = re.findall(r'\d*-\d*-\d*',upTimesStr)[0]# 上映时间resultData['time'] = upTimeif soup.find('span',property='v:runtime'):# 时间长度resultData['moveiTime'] = re.findall(r'\d+',soup.find('span',property='v:runtime').get_text())[0]else:# 时间长度resultData['moveiTime'] = random.randint(39,61)# 评论个数resultData['comment_len'] = soup.find('span',property='v:votes').get_text()starts = []startAll = soup.find_all('span',class_='rating_per')for i in startAll:starts.append(i.get_text())# 星星比例(数组)resultData['starts'] = ','.join(starts)# 影片简介resultData['summary'] = soup.find('span',property='v:summary').get_text().strip()# 五条热评comments_info = soup.find_all('span', class_='comment-info')comments = [{} for x in range(5)]for i, comment in enumerate(comments_info):comments[i]['user'] = comment.contents[1].get_text()comments[i]['start'] = re.findall('(\d*)', comment.contents[5].attrs['class'][0])[7]comments[i]['time'] = comment.contents[7].attrs['title']contents = soup.find_all('span', class_='short')for i in range(5):comments[i]['content'] = contents[i].get_text()resultData['comments'] = json.dumps(comments)# 五张详情图imgList = []lis = soup.select('.related-pic-bd img')for i in lis:imgList.append(i['src'])resultData['imgList'] = ','.join(imgList)

将结果保存到CSV文件和SQL数据库中,并在完成后更新页数记录。

从豆瓣电影数据中提取演员和导演的电影数量信息,以便后续的分析和可视化展示。

def getAllActorMovieNum():allData = homeData.getAllData()ActorMovieNum = {}for i in allData:for j in i[1]:if ActorMovieNum.get(j,-1) == -1:ActorMovieNum[j] = 1else:ActorMovieNum[j] = ActorMovieNum[j] + 1ActorMovieNum = sorted(ActorMovieNum.items(), key=lambda x: x[1])[-20:]x = []y = []for i in ActorMovieNum:x.append(i[0])y.append(i[1])return x,y

定义统计导演执导电影数量的函数getAllDirectorMovieNum():

def getAllDirectorMovieNum():allData = homeData.getAllData()ActorMovieNum = {}for i in allData:for j in i[4]:if ActorMovieNum.get(j,-1) == -1:ActorMovieNum[j] = 1else:ActorMovieNum[j] = ActorMovieNum[j] + 1ActorMovieNum = sorted(ActorMovieNum.items(), key=lambda x: x[1])[-20:]x = []y = []for i in ActorMovieNum:x.append(i[0])y.append(i[1])return x,y
  1. allData = homeData.getAllData():调用homeData模块中的getAllData函数,获取所有的电影数据,并将其保存在allData变量中。
  2. ActorMovieNum = {}:创建一个空字典ActorMovieNum,用于存储导演与其执导电影数量的映射。
  3. for i in allData::遍历所有电影数据,其中i代表每一部电影的信息。
  4. for j in i[4]::在每部电影的信息中,使用i[4]访问导演的信息,然后遍历每个导演。
  5. if ActorMovieNum.get(j, -1) == -1::检查字典ActorMovieNum中是否已经存在该导演的记录。如果不存在,则将该导演作为键加入字典,并将对应的值初始化为1。
  6. else::如果字典中已存在该导演的记录,则将对应的值加1,表示该导演又执导了一部电影。
  7. ActorMovieNum = sorted(ActorMovieNum.items(), key=lambda x: x[1])[-20:]:将字典中的导演及其执导电影数量按照电影数量进行降序排序,然后取排序后的前20项。排序的依据是key=lambda x: x[1],即按照字典中的值进行排序。
  8. x = []y = []:创建两个空列表,用于存储导演名称和对应的执导电影数量。
  9. for i in ActorMovieNum::遍历排序后的前20项导演及其执导电影数量。
  10. x.append(i[0])y.append(i[1]):将导演的名称和执导电影数量分别加入列表xy
  11. return x, y:返回存储导演名称和执导电影数量的两个列表。

从名为homeData的模块中导入getAllData函数,然后使用pandas库创建一个数据框(DataFrame)dfgetAllData函数的返回值被传递给DataFrame的构造函数,同时指定了数据框的列名。

  1. from . import homeData: 这行代码从当前目录(.表示当前目录)导入homeData模块。
  2. import pandas as ps: 这行代码导入pandas库,并使用ps作为别名。一般来说,pandas的别名是pd,但在这里使用了ps
  3. df = ps.DataFrame(homeData.getAllData(), columns=[...]): 这行代码创建一个数据框df,并使用homeData.getAllData()的返回值填充数据框。列名由columns参数指定,列的顺序与列表中的顺序相对应。列名包括:
    • ‘id’: 电影ID
    • ‘directors’: 导演
    • ‘rate’: 评分
    • ‘title’: 标题
    • ‘casts’: 演员
    • ‘cover’: 封面
    • ‘year’: 上映年份
    • ‘types’: 类型
    • ‘country’: 制片国家
    • ‘lang’: 语言
    • ‘time’: 时长
    • ‘moveiTime’: 电影时长
    • ‘comment_len’: 评论长度
    • ‘starts’: 星级
    • ‘summary’: 摘要
    • ‘comments’: 评论
    • ‘imgList’: 图片列表
    • ‘movieUrl’: 电影链接
    • ‘detailLink’: 详细链接

这样就创建了一个包含特定列名的数据框,其中的数据来自homeData.getAllData()函数的返回结果。

from . import homeData
import pandas as ps
df = ps.DataFrame(homeData.getAllData(),columns=['id','directors','rate','title','casts','cover','year','types','country','lang','time','moveiTime','comment_len','starts','summary','comments','imgList','movieUrl','detailLink'])

从数据框(DataFrame)中的’country’列中提取地址数据。数据框中的地址数据提取出来,并统计每个地址出现的次数。它首先检查’country’列中的每个元素,如果元素是一个列表,则将列表中的每个元素添加到一个新的列表(address)中。然后,它创建一个字典(addressDic),将地址作为键,出现次数作为值,最后返回地址列表和对应的出现次数列表。

def getAddressData():# 获取名为 'country' 的列的值addresses = df['country'].values# 创建一个空列表来存储地址address = []# 遍历 'country' 列的每个元素for i in addresses:# 如果元素是列表类型if isinstance(i, list):# 遍历列表中的每个元素并添加到 address 列表中for j in i:address.append(j)else:# 如果元素不是列表类型,直接将其添加到 address 列表中address.append(i)# 创建一个空字典来存储地址及其出现次数addressDic = {}# 遍历地址列表中的每个元素for i in address:# 如果地址字典中不存在该地址,则将其添加并设置出现次数为1if addressDic.get(i, -1) == -1:addressDic[i] = 1else:# 如果地址字典中已存在该地址,则将其出现次数加1addressDic[i] = addressDic[i] + 1# 返回地址列表和对应的出现次数列表return list(addressDic.keys()), list(addressDic.values())

从数据框的’lang’列中提取语言数据,并统计每种语言出现的次数。最终返回语言列表和对应的出现次数列表。

def getLangData():# 获取名为 'lang' 的列的值langs = df['lang'].values# 创建一个空列表来存储语言数据languages = []# 遍历 'lang' 列的每个元素for i in langs:# 如果元素是列表类型if isinstance(i, list):# 遍历列表中的每个元素并添加到 languages 列表中for j in i:languages.append(j)else:# 如果元素不是列表类型,直接将其添加到 languages 列表中languages.append(i)# 创建一个空字典来存储语言及其出现次数langsDic = {}# 遍历语言列表中的每个元素for i in languages:# 如果语言字典中不存在该语言,则将其添加并设置出现次数为1if langsDic.get(i, -1) == -1:langsDic[i] = 1else:# 如果语言字典中已存在该语言,则将其出现次数加1langsDic[i] = langsDic[i] + 1# 返回语言列表和对应的出现次数列表return list(langsDic.keys()), list(langsDic.values())

数据库创建四个表:
在这里插入图片描述
在这里插入图片描述
修改为自己的数据库主机名和账号密码:
在这里插入图片描述
启动项目:
在这里插入图片描述

服务端口:5000 http://127.0.0.1:5000

用户注册 http://127.0.0.1:5000/registry

在这里插入图片描述

用户登录

在这里插入图片描述

首页页面展示:

在这里插入图片描述

还有电影数据,包括电影名、评分、片场、预告片等数据。

在这里插入图片描述

查看电影预告片

在这里插入图片描述

电影搜索

在这里插入图片描述

电影产量分析

在这里插入图片描述

电影数据时长分布占比

在这里插入图片描述

电影评分统计分析

在这里插入图片描述

在这里插入图片描述

​ 豆瓣评分星级饼状图、豆瓣年度评价评分柱状图

在这里插入图片描述

​ 豆瓣电影中外评分分布图

在这里插入图片描述

数据视图切换

在这里插入图片描述
在这里插入图片描述

​ 电影拍摄地点统计图

在这里插入图片描述

​ 电影语言统计图

在这里插入图片描述

电影类型饼图

在这里插入图片描述

​ 导演作品数量前20

在这里插入图片描述

在这里插入图片描述

​ 数据表操作

在这里插入图片描述

​ 标题词云图

在这里插入图片描述

​ 简介词云图

在这里插入图片描述
s4XV8qh-1701860368769)

​ 演员名词云图

在这里插入图片描述

评论词云图

在这里插入图片描述
在这里插入图片描述
经过对一系列测试结果的有效分析,本平台开发系统符合用户的要求和需求。所有的基本功能齐全,可视化展示效果好,服务运行稳定,操作起来简单方便,测试系统性能、整体设计和代码逻辑都很Nice!

各位有兴趣的小伙伴 可以私信我要项目开发文档、完整项目源码和其它相关资料

后面有时间和精力也会分享更多关于大数据领域方面的优质内容,喜欢的小伙伴可以点赞关注收藏,有需要的都可以私信我!感谢各位的喜欢与支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/211896.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统思考与啤酒游戏经营沙盘

结束一家汽车零配件公司《系统思考与啤酒游戏经营沙盘》的内训课,4个小组基本上都有共同的心智模式,这也代表团队有一些集体的盲点。不仅仅对啤酒游戏经营沙盘做了复盘,同时也借用学员画出的系统环路图完成真实案例的研讨以及团队共识&#x…

宏工科技:电池装备高效交付“唯快不破”

面向TWh时代的锂电设备供应需求,锂电设备向标准化、模块化方向升级的趋势显现。 “近年来,宏工科技聚焦电池匀浆技术创新与规模化降本,通过电池匀浆工艺段的模块化探索与应用,从项目周期、成本、效率等多维度赋能电池前段制造高质…

Ubuntur编译ROS报错:error PCL requires C++14 or above

ubuntu20.04 编译ROS包 报错: error: PCL requires C14 or above: 修改Cmakelists.txt文件: set(CMAKE_CXX_STANDARD 14) 再次编译成功.

图纸加密防泄密软件排名

图纸作为企业的重要资产,如何保护其安全,防止泄密,成为了企业亟待解决的问题。而图纸加密防泄密软件,正是解决这一问题的有效工具。 一、图纸加密防泄密软件的重要性 图纸加密防泄密软件通过对图纸进行加密处理,使得只…

重估拼多多,TEMU带给拼多多的不止是市值增量

监制 | 何玺 排版 | 叶媛 谁也没有想到,中国电商的格局改变居然如此之快。 12月29日,拼多多市值超越多年雄踞国内电商头把交椅的阿里巴巴,成为美股市值最大中概股。从此时开始,中国电商开始“拼”时代。 拼多多凭什么能超越阿里…

MySQL 包含查询特殊符号数据

当你模糊查询包含特殊符号的数据时,如果不加上特殊处理,查询结果是错误的。 如果你查的数据包含如上字符或者其他特殊字符,需要加上\转义字符。 如下示例: SELECT * FROM t_bc_user t where t.name LIKE %\_%

qt 5.15.2 主窗体菜单工具栏树控件功能

qt 5.15.2 主窗体菜单工具栏树控件功能 显示主窗体效果&#xff1a; mainwindow.h文件内容&#xff1a; #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QFileDialog> #include <QString> #include <QMessageBox>#inc…

基于GUI+Swing+MySQL开发的聊天室设计

基于GUISwingMySQL开发的聊天室设计 项目介绍&#x1f481;&#x1f3fb; 本项目是基于Java Swing的聊天室设计&#xff0c;旨在为用户提供一个便捷、高效的在线交流平台。在这个项目中&#xff0c;我们实现了以下几个主要功能&#xff1a; 1. 服务器启动成功&#xff1a;当用户…

Java实现动态加载的逻辑

日常工作中我们经常遇到这样的场景&#xff0c;某某些逻辑特别不稳定&#xff0c;随时根据线上实际情况做调整&#xff0c;比如商品里的评分逻辑&#xff0c;比如规则引擎里的规则。 常见的可选方案有: JDK自带的ScriptEngine 使用groovy&#xff0c;如GroovyClassLoader、Gro…

【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(1)spring boot项目搭建、vue项目搭建、微信小程序项目搭建

项目笔记为项目总结笔记,若有错误欢迎指出哟~ 【项目专栏】 【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(1)项目搭建 持续更新中… java+vue+微信小程序项目】从零开始搭建——健身房管理平台 项目简介Java项目搭建(IDEA)1.新建项目2.项目类型3.项目设置4…

react native 环境准备

一、必备安装 1、安装node 注意 Node 的版本应大于等于 16&#xff0c;安装完 Node 后建议设置 npm 镜像&#xff08;淘宝源&#xff09;以加速后面的过程&#xff08;或使用科学上网工具&#xff09;。 node下载地址&#xff1a;Download | Node.js设置淘宝源 npm config s…

【T+】畅捷通T+软件安装过程中停留在:正在配置产品位置或进度80%位置。

【问题描述】 畅捷通T软件在安装过程中&#xff0c; 进度条一直停留在【正在配置产品…】位置。 【解决方法】 打开【任务管理器】&#xff0c;想必这个如何打开&#xff0c;大家应该都会。 在【进程】中找到【DBConfig.exe】或者【Ufida.T.Tool.SM.DBConfig.exe】进程并结束…

【keil备忘录】2. stm32 keil仿真时的时间测量功能

配置仿真器Trace内核时钟为单片机实际的内核时钟&#xff0c;需要勾选Enable设置&#xff0c;设置完成后Enable取消勾选也可以&#xff0c;经测试时钟频率配置仍然生效&#xff0c;此处设置为48MHZ: 时间测量时必须打开register窗口&#xff0c;否则可能不会计数 右下角有计…

基于瑞芯微rk3588+寒武纪 | 38TOPS INT8算力的AI边缘计算盒子,智能安防、智慧工地、智慧城管、智慧油站

边缘计算盒子 瑞芯微rk3588寒武纪 | 38TOPS INT8算力 ● 采用 Big-Little 大小核架构&#xff0c;搭载四核 A76四核 A55&#xff0c;CPU主频高达 2.4GHz &#xff0c;提供1MB L2 Cache 和 3MB L3 &#xff0c;Cache提供更强的 CPU 运算能力。 ● 高性能四核 Mali-G610 GPU&a…

DAPP开发【06】nodejs安装与npm路径更换

windows系统在执行用户命令时顺序 windows系统在执行用户命令时&#xff0c;若用户未给出文件的绝对路径&#xff0c; 则 &#xff08;1&#xff09;首先在当前目录下寻找相应的可执行文件、批处理文件等&#xff1b; &#xff08;2&#xff09;若找不到&#xff0c;再依次在系…

uni-app 微信小程序之自定义navigationBar顶部导航栏

文章目录 1. 实现效果2. App.vue3. pages.json 配置自定义4. 顶部导航栏 使用 微信小程序自定义 navigationBar 顶部导航栏&#xff0c;兼容适配所有机型 1. 实现效果 2. App.vue 在App.vue 中&#xff0c;设置获取的 StatusBar&#xff0c;CustomBar 高度&#xff08;实现适配…

Stm32_串口的帧(不定长)数据接收

目录标题 前言1、串口中断接收固定帧头帧尾数据1.1、任务需求1.2、实现思路1.3、程序源码&#xff1a; 2、串口中断接收用定时器来判断帧结束3、串口中断接收数据空闲中断3.1、串口的空闲中断3.2、实现思路3.3、程序源码 4、串口的空闲中断DMA转运4.1、DMA简介4.2、DMA模式4.3、…

基于ssm人事管理信息系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本人事管理信息系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

c++函数模板STL详解

函数模板 函数模板语法 所谓函数模板&#xff0c;实际上是建立一个通用函数&#xff0c;其函数类型和形参类型不具体指定&#xff0c;用一个虚拟的类型来代表。这个通用函数就称为函数模板。 凡是函数体相同的函数都可以用这个模板来代替&#xff0c;不必定义多个函数&#xf…

外包干了3个月,技术倒退2年。。。

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…