数据可视化案例

数据可视化案例

使用豆瓣电影中的数据来进行可视化,网址:豆瓣电影 Top 250 (douban.com)

一、网页数据分析

在这里插入图片描述

我们需要爬取的是豆瓣电影Top250网页每一页电影名称图片链接导演年份国家电影类型电影评分这些数据。

在待爬取的网页中,按下F12键进入开发者模式,这样可以让我们很方便的找到网页中每一块数据对应的源码。

在这里插入图片描述

通过以上方式可以让我们很快的找到图片对应的标签,通过观察,我们可以找到每一个图片的链接都存放在<img>标签的src属性下。

同样的,我们可以找到电影名称所在的标签。
请添加图片描述

可以知道电影名称所在的位置是<span>标签的值。

在这里插入图片描述

我们可以发现导演、年份、国家类型都在<p>标签下,这种情况我们就需要后期的处理了,先简单的得到<p>标签的数据,然后再通过字符串的分割、选取、剔除等操作可以得到最终我们需要的数据。
在这里插入图片描述

最后一个是评分标签,我们通过同样的方式可以找到评分在<span class="rating_num">标签中,并且是<span class="rating_num">标签的值。

由于我们需要的是每一页的标签,一个简单的可行的思路是找到后页标签对应的标签,这里找到的是<a>标签,<a>标签属性href的值对应的是下一页的网址,如果<a>标签的属性为空时,说明没有下一页了,可以停止爬取了。
在这里插入图片描述

通过以上分析,我们开始编写爬虫程序来爬取数据,这里我们使用scrapy爬虫框架来进行爬取数据。

二、数据爬取(获取数据)

1. 安装scrapy

pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 初始化scrapy项目

scrapy startproject Douban

在这里插入图片描述

使用PyCharm打开项目,可以观察到项目的整体结构如下:

在这里插入图片描述

3. 设置数据结构

items.py文件

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass DoubanItem(scrapy.Item):imgUrl = scrapy.Field()  # 图片链接name = scrapy.Field()   # 电影名称author = scrapy.Field()  # 导演名称year = scrapy.Field()   # 年份country = scrapy.Field()  # 国家types = scrapy.Field()   # 电影类型score = scrapy.Field()   # 电影评分

4. 创建爬虫程序

scrapy genspider douban "movie.douban.com"   # douban是爬虫的名称, "movie.douban.com"是要爬取网址的域名

在这里插入图片描述

在这里插入图片描述

打开爬虫文件,更改带爬取的文件的网址:

在这里插入图片描述

编写爬虫程序douban.py
import scrapy
from ..items import DoubanItemclass DoubanSpider(scrapy.Spider):name = "douban"allowed_domains = ["movie.douban.com"]start_urls = ["https://movie.douban.com/top250"]def parse(self, response):doubans = response.xpath("//ol[@class='grid_view']/li")for douban in doubans:item = DoubanItem()item['name'] = douban.xpath("div[@class='item']/div[2]/div[1]/a/span/text()").extract_first()item['imgUrl'] = douban.xpath("div/div[@class='pic']/a/@href").extract_first()text = douban.xpath("div/div[@class='info']/div[@class='bd']/p/text()").extract()[1]fs_text = douban.xpath("div/div[@class='info']/div[@class='bd']/p/text()").extract()[0]item['author'] = fs_text.split(" ")[0].strip().split(" ")[1: -1]item['score'] = douban.xpath("div/div[@class='info']/div[2]/div[@class='star']/span[2]/text()").extract_first()c_start = text.find("/")c_end = text.find("/", c_start + 1)country = text[c_start + 1: c_end]year = text[: c_start]types = text[c_end:]country_analyse = country.split(" ")country_have = country_analyse[1].split(" ") if len(country_analyse) > 1 else country_analyse[0].split(" ")item['country'] = country_have if country_have != [""] else ["中国大陆"]item['year'] = year.split(" ")[0].strip()item['types'] = types.split(" ")[1].strip().split(" ")yield itemnext_page = response.xpath("/html/body/div[3]/div[1]/div[1]/div[1]/div[2]/span[3]/a/@href").extract_first()if next_page:yield response.follow(next_page, self.parse)
配置settings.py文件:
  1. 首先设置代理USER_AGENT
# 第17行
USER_AGENT  = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
  1. 设置不服从ROBOOTS协议:
ROBOTSTXT_OBEY = False    # 第20行

5. 运行爬虫程序

scrapy crawl douban -o ./Data/douban.json 

在这里插入图片描述

在这里插入图片描述

打开douban.json数据可以查看到爬取到的结果:

在这里插入图片描述

三、数据处理与可视化

数据处理部分,我们使用Pandas库来对数据进行处理,可视化部分,我们使用pyecharts库来进行数据可视化。

pyecharts参考网站:pyecharts

创建目录结构:
在这里插入图片描述

数据处理:

编写DataAnalyze.py文件
import json
import pandas as pdpath = '../Data/douban.json'
with open(path, 'r', encoding='utf-8') as file:global datadata = json.load(file)def YearNumTop_5() -> tuple:''':return: 发布电影次数最多的前五名年份以及电影次数'''years = []for movie in data:years.append(movie['year'][:4])# 统计数据出现的次数y = pd.Series(years)y_count = y.value_counts()   # value_counts函数会统计次数并且进行自动的排序,降序y_count = y_count.head(5)# print(y_count)x_list = y_count.index.tolist()   # 将索引转换为列表y_list = y_count.values.tolist()   # 将值转换为列表# print(x_list, y_list)return (x_list, y_list)def TpyeNum() -> tuple:''':return: 电影类型及类型出现的次数'''types = []for type in data:types.extend(type['types'])# print(types)tp = pd.Series(types)tp = tp.value_counts()[1: -2]tp_label = tp.index.tolist()  # tolist用于将pandas中的Series或DataFrame转换为列表对象tp_count = tp.values.tolist()# print(tp_label, tp_count)return (tp_label, tp_count)def YearMovies() -> tuple:''':return: 年份,以及每一年的电影'''name = []year = []tree_dict = {}for movie in data:name.append(movie["name"])year.append(movie['year'])for n, y in zip(name, year):# print(z)# print(n, y)if tree_dict.get(y) is None:tree_dict[y] = [n]  # 如果键不存在,初始化为列表else:tree_dict[y].append(n)# 我们只取得前5年的数据keys_sliced = list(tree_dict.keys())[0: 5]tree_part = {key: tree_dict[key] for key in keys_sliced}# print(keys_sliced, tree_part)return (keys_sliced, tree_part)def CountryNum() -> tuple:''':return: 返回国家以及每个国家的电影数量'''country = []for movie in data:country.extend(movie['country'])# print(country)cou = pd.Series(country)cou_sort = cou.value_counts()country_ans = cou_sort.index.tolist()count_ans = cou_sort.values.tolist()# print(country_ans, count_ans)return (country_ans, count_ans)if __name__ == '__main__':CountryNum()

可视化:

1. 锥形图
from pyecharts import options as opts
from pyecharts.charts import Funnel
from DataAnalyze import YearNumTop_5data = YearNumTop_5()funnel_table = (Funnel().add("年份-电影数量", [list(z) for z in zip(data[0], data[1])]).set_global_opts(title_opts=opts.TitleOpts(title="Top-5")).render("../SourceChart/Funnel.html")
)

在这里插入图片描述

2. 词云图
from pyecharts import options as opts
from pyecharts.charts import WordCloud
from pyecharts.globals import SymbolType
from DataAnalyze import TypeNumlabel, count = TypeNum()
words = [(l, c) for l, c in zip(label, count)]   # 使用列表生成式,生成元素为元组的列表wordCloud = (WordCloud().add("电影类型", words, word_size_range=[20, 100], shape=SymbolType.DIAMOND).set_global_opts(title_opts=opts.TitleOpts(title="Movie Type Distribution")).render("../SourceChart/WordCloud.html")
)

在这里插入图片描述

3. 雷达图
from pyecharts import options as opts
from pyecharts.charts import Radar
from DataAnalyze import TypeNumtypes = TypeNum()data = [{"value": types[1], "name": "电影类型"}]
# 设置雷达图的取值范围,最大为57,最小为0
max = 57
min = 0c_schema = [{"name": name, "max": max, "min": min} for name in types[0]
]radar = (Radar().set_colors(["#4587E7"]).add_schema(schema=c_schema,shape="circle",center=["50%", "50%"],radius="80%",angleaxis_opts=opts.AngleAxisOpts(min_=0,max_=360,is_clockwise=False,interval=5,axistick_opts=opts.AxisTickOpts(is_show=False),axislabel_opts=opts.LabelOpts(is_show=False),axisline_opts=opts.AxisLineOpts(is_show=False),splitline_opts=opts.SplitLineOpts(is_show=False),),radiusaxis_opts=opts.RadiusAxisOpts(min_=min,max_=max,interval=2,splitarea_opts=opts.SplitAreaOpts(is_show=True, areastyle_opts=opts.AreaStyleOpts(opacity=1)),),polar_opts=opts.PolarOpts(),splitarea_opt=opts.SplitAreaOpts(is_show=False),splitline_opt=opts.SplitLineOpts(is_show=False),).add(series_name="电影分类",data=data,areastyle_opts=opts.AreaStyleOpts(opacity=0.1),linestyle_opts=opts.LineStyleOpts(width=1),).render("../SourceChart/Radar.html")
)

在这里插入图片描述

4. 树图
import pyecharts.options as opts
from pyecharts.charts import Tree
from DataAnalyze import YearMoviesyear, movie_data = YearMovies()# 构造类似于递归字典的数据类型
for y in year:movie_data[y] = [{"name": value, "children": 1} for value in movie_data[y]]
data = [{'name': y, 'children': movie_data[y]} for y in year]
data = {'name': "电影", 'children': data}tree = (Tree().add(series_name="",data=[data],pos_top="18%",pos_bottom="14%",layout="radial",symbol="emptyCircle",symbol_size=7,).set_global_opts(tooltip_opts=opts.TooltipOpts(trigger="item", trigger_on="mousemove")).render("../SourceChart/Tree.html")
)

在这里插入图片描述

5. 地图
from pyecharts import options as opts
from pyecharts.charts import Map
from DataAnalyze import CountryNum
from translate import Translator# 实例话翻译类:从中文翻译为英文
translator = Translator(from_lang="Chinese", to_lang="English")
data = CountryNum()
# 对每一个数据进行翻译
for idx, cou in enumerate(data[0]):if cou == "美国":data[0][idx] = "United States"continueif cou == "英国":data[0][idx] = "United Kingdom"continueif cou in ["中国大陆", "中国香港", "中国台湾", "1964(中国大陆)"]:cou = "中国"target = translator.translate(f'{cou}')data[0][idx] = targetif idx % 5 == 0:print(target)map_table = (Map().add("上映地区", [list(z) for z in zip(data[0], data[1])], "world").set_series_opts(label_opts=opts.LabelOpts(is_show=False)).set_global_opts(title_opts=opts.TitleOpts(title="Map-世界地图"),visualmap_opts=opts.VisualMapOpts(max_=145),).render("../SourceChart/Map.html")
)

在这里插入图片描述

5. 将所有图汇总到一张网页上

如果要把所有图表汇总到一个网页上,那么需要将每一个绘制图的./render给注释掉,类似与下面这样,否则会将图表识别为字符串类型的数据。

在这里插入图片描述

Summary.py

from pyecharts.charts import Page
from Funnel import funnel_table
from Map import map_table
from Radar import radar
from Tree import tree
from WordCloud import wordCloud# 初始化网页
page = Page(layout=Page.DraggablePageLayout)
page.add(map_table)  # 添加地图
page.add(radar)      # 添加雷达图
page.add(tree)      # 添加树图
page.add(wordCloud)  # 添加词云图
page.add(funnel_table)     # 添加漏斗图
page.render("../SourceChart/Summary.html")

在这里插入图片描述

声明:本项目只用于学习,禁止用于任何非法的行为。—— 2024.6.16

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

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

相关文章

通义千问调用笔记

如何使用通义千问API_模型服务灵积(DashScope)-阿里云帮助中心 package com.ruoyi.webapp.utils;import com.alibaba.dashscope.aigc.generation.Generation; import com.alibaba.dashscope.aigc.generation.GenerationOutput; import com.alibaba.dashscope.aigc.generation.G…

移动硬盘打不开怎么办?原因解析!

移动硬盘是一种方便携带、快速传输大量数据的存储设备。但有时我们会遇到这样的问题&#xff1a;插上电脑后&#xff0c;移动硬盘无法打开&#xff0c;出现各种错误提示。这时候我们该怎么办呢&#xff1f; 以下是一些可能导致移动硬盘打不开的原因及解决方法&#xff1a; 1.硬…

初始-Nativefier

--无奈只能靠自己 Nativefier 是什么&#xff1a; Nativefier 是一个命令行工具&#xff0c;仅仅通过一行代码就可以轻松地为任何的网站创建桌面应用程序&#xff0c;应用程序通过 Electron 打包成系统可执行文件&#xff08;如.app, .exe 等&#xff09;&#xff0c;可以运行在…

xx销售公司IT建设目标及IT规划方案(69页PPT)

方案介绍&#xff1a; 随着市场竞争的日益激烈&#xff0c;XX销售公司认识到信息化建设对于提升公司竞争力、优化业务流程、提高管理效率的重要性。次IT建设方案为XX销售公司带来了显著的业务效益和管理提升。我们将继续致力于推动公司的信息化建设&#xff0c;为公司的发展提…

Arthas线上环境问题排查定位工具

一、Arthas简介 Arthas是alibaba推出的一款JVM性能诊断调优的工具&#xff0c;也可以称之为是线上监控诊断产品&#xff0c;通过全局的视角可以实时的查看应用load、内存、GC、线程的状态信息&#xff0c;并且还可以在不修改应用代码的前提下&#xff0c;对业务问题进行诊断&a…

手把手教你如何在Windows11下安装Docker容器

文章的主要要点&#xff1a; 为什么使用Docker&#xff1a;Docker可以简化部署过程&#xff0c;特别适合新手或在学习新技能&#xff08;如Redis、MySQL、消息队列、Nginx等&#xff09;时使用。 安装前的准备&#xff1a;在安装Docker之前&#xff0c;需要在Windows中开启一些…

2024都市解压爆笑喜剧《脑洞大开》6月28日上映

随着暑期档的临近&#xff0c;电影市场迎来了一剂强心针——由何欢、王迅、克拉拉、卜钰、孙越、九孔等众多实力派笑星联袂主演的都市解压爆笑喜剧《脑洞大开》正式宣布定档&#xff0c;将于6月28日在全国各大影院欢乐上映&#xff0c;誓为观众带来今夏最畅快淋漓的笑声风暴。 …

代码随想录-Day32

122. 买卖股票的最佳时机 II 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一天 出售。 返回 你能…

MicroPython+ESP32 C3开发上云

传感器PinI/O状态D412输出1开0关D513输出1开0关 概述 MicroPython是python3编程语言的精简实现&#xff0c;能够在资源非常有限的硬件上运行&#xff0c;如MCU微控制器Micropython的网络功能和计算功能很强大&#xff0c;有非常多的库可以使用&#xff0c;它为嵌入式开发带来了…

FFmpeg编解码的那些事(3)-视频硬解码的基础知识

目录 前言&#xff1a; 1.iso/os x平台 2.windows平台 3.linux平台 4.Tips&#xff1a; 5.结论&#xff1a; 前言&#xff1a; 视频硬解码的过程就是把视频提取成图片变显示出来&#xff0c;就是播放器播放视频的过程&#xff0c;就可以理解为解码的过程。 在不同的系统…

【Android面试八股文】Java中有几种引用关系,它们的区别是什么?

在Java中,引用关系主要分为以下几种: 强引用(Strong Reference)软引用(Soft Reference)弱引用(Weak Reference)虚引用(Phantom Reference) 这些引用类型的区别在于它们对垃圾回收的影响程度。下面是对每种引用类型的详细解释及代码示例: 1. 强引用(Strong Referen…

LabVIEW、Matlab与Python的比较:从多角度详解三大编程工具

LabVIEW、Matlab和Python是工程和科学领域中常用的编程工具&#xff0c;各具特色。本文将从开发效率、计算性能、应用场景、学习曲线、成本和社区支持等多个角度&#xff0c;详细比较这三者的优缺点&#xff0c;帮助读者选择最适合其项目需求的编程工具。 比较维度 开发效率 La…

扫地机LiDAR形态之美

石头扫地机V20 LiDAR: Flash光源和Spot光源切换 图来自 Robot森 LiDAR(Light Detection and Ranging,激光雷达)技术在扫地机器人中的应用,不仅提升了机器的智能性和实用性,还展现了一种科技与艺术的融合之美。 一、外观设计的精致性 紧凑与轻巧:扫地机器人的LiDAR传感器…

C++ 43 之 自增运算符的重载

#include <iostream> #include <string> using namespace std;class MyInt{friend ostream& operator<< (ostream& cout , MyInt& int1); public:MyInt(){this->m_num 0;}// 前置自增&#xff1a; 成员函数实现运算符的重载 返回的是 引用&a…

STM32CubeMX配置-RTC周期唤醒

一、简介 MCU为STM32G070&#xff0c;采用内部时钟32KHZ&#xff0c;配置为周期6s唤醒&#xff0c;调用回调函数&#xff0c;进行喂狗操作。 二、配置 初始时间、日期、周期唤醒时间配置。 开启周期唤醒中断 三、生成代码 调用回调函数&#xff0c;进行喂狗操作。 //RTC唤醒回…

Java NIO ByteBuffer 使用方法

前言 最近在使用spring boot websocket xterm.js 给 k8s pod做了个在线的 web 终端&#xff0c;发现websocket的类核心方法&#xff0c;用的都是ByteBuffer传递数据&#xff0c;如下&#xff1a; OnMessagepublic void onMessage(Session session, ByteBuffer byteBuffer) {…

vitepress搭建的博客系统cdn引入github discussions评论系统

github仓库必须是公开的。 按照CDN的方式引入 打开discussions模块 安装giscus app 配置giscus 就是刚安装了giscus app的仓库 页面往下走&#xff0c;生成了代码&#xff1a; 配置vitepress 采用了CDN的方式引入 使用web component 随便找个地方试试组件 效果 有了…

LeetCode43.字符串相乘【大整数相乘】

LeetCode刷题记录 文章目录 &#x1f4dc;题目描述&#x1f4a1;解题思路 &#x1f4dc;题目描述 给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 注意&#xff1a;不能使用任何内置的 Big…

记录一次centos扩容

背景 在Vscode上连虚拟机写项目&#xff0c;突然提示磁盘空间不足(no space left on device)&#xff0c;一开始打算删些东西&#xff0c;这里参考博客&#xff0c;写得挺清楚的&#xff0c;但是操作后我发现实在没啥文件可以删除&#xff0c;所以干脆不删了&#xff0c;直接扩…

创建comfyui自定义节点

参考 https://github.com/liubai-liubai/ComfyUI-ImgSeg-LB/tree/main https://blog.styxhelix.life/?p33 安装 不需要安装任何其他依赖文件&#xff0c;只需要把0x_erthor_node文件夹复制到custom_nodes文件夹下&#xff0c;就能安装成功。 a1&#xff1a;展示了代码结构&…