当前位置: 首页 > news >正文

爬虫数据清洗可视化案例之全球灾害数据

目标网站:全球灾害数据平台
温馨提示: 仅供学习交流使用

本案例所使用的库
requests()lxml
pandasnumpy
matplotlibseaborn
pprint

明确需要爬取的内容:

  • 国家地区

  • 所属洲

  • 总频次

  • 受影响人口(万人)

  • 死亡人口(人)

  • 经济损失(千美元)

爬取步骤:

  1. 发送请求  模拟浏览器向服务器 发送请求

  2. 解析数据  提取想要的数据

  3. 保存数据  持久化保存  csv  excel 数据库

一.发送请求

确定网页的构造  静态数据 or 动态数据
右击查看网页源代码   Ctrl+F  再搜索框中输入要获取的信息

返回的结果是没有  说明是动态的数据  需要抓包分析

此时 到网页主界面  快捷键(F12) or 右击 检查

点击网络  接着刷新当前界面  或 Ctrl+R(快捷键刷新)

同样地  Ctrl+F 打开搜索框 输入想获取的数据 在返回中的数据包中筛选  找到符合的那个

然后 点击标头  这里有请求的一些基本信息 可以查看  

我们使用爬虫工具 快速构建 爬虫请求代码

右击相应的数据包  点击复制cURL(bash) 如上图所示  注意是bash

之后打开 工具  爬虫工具库-spidertools.cn

复制右边的代码 到Pycharm中

运行代码  检查想爬取的数据是否在返回的数据中

二. 解析数据

因为返回的是Json格式的数据  需要获取 返回的Json

这里我们可以使用  python 模块 pprint 可以让Json 格式的数据更加美观

import pprintpprint.pprint(response.json())

这样输出就会如下图所示

对比页面 找到想要爬取数据的位置 字段名

接着我们从 字典套列表的格式中提取数据  通过键值对取值  For循环遍历列表 取值

json_data = response.json()['data']['content']# 拿到想要的数据
for li in json_data:country = li['countryCn']state = li['continentCn']total = li['sum']death_people = li['death']influence_people = li['population']found_lose = li['loss']# 可以输出打印 对比数据是否符合

三. 保存数据

保存数据为 Excel文件

# 先将数据存储到 字典中
# 再定义一个列表  将数据添加进去
dit = {'国家': country,'州': state,'总频次': total,'死亡人数': death_people,'影响人数': influence_people,'损失': found_lose}# 保存数据 为excel
pd.DataFrame(lis).to_excel('global_disaster.xlsx',index=False)

多页爬取  查看请求体里面的data参数  直接 修改 循环即可  我这里写它全部的数据

温馨提示: 它这个  "Authorization" 参数具有时效性   逆向可解决 但不影响我们获取数据

这样就爬取到了我们想要的数据

以下是爬虫部分的全部代码

import pprintimport pandas as pd
import requests
import jsonheaders = {"Accept": "application/json, text/plain, */*","Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6","Authorization": "Bearer b81b81e2-da54-4548-ac4f-4504ba437b51","Cache-Control": "no-cache","Connection": "keep-alive","Content-Type": "application/json;charset=UTF-8","Origin": "https://www.gddat.cn","Pragma": "no-cache","Referer": "https://www.gddat.cn/newGlobalWeb/","Sec-Fetch-Dest": "empty","Sec-Fetch-Mode": "cors","Sec-Fetch-Site": "same-origin","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0","sec-ch-ua": "\"Microsoft Edge\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "\"Windows\""
}
cookies = {"你的cookie"
}
url = "https://www.gddat.cn/gw/application-base-ris-portal/featureAnalysis/idisasterEmdatStandard/getIHistoryByCountry"
data = {"continentCn": "","frequency": "10","continent": [],"countryCode": [],"eventTypeCode": [],"maxaffected": "","maxdeaths": "","maxloss": "","minaffected": "","mindeaths": "","minloss": "","orderby": "sum","fromYear": "","toYear": "","Year": "","page": 0,"size": 204,
}
data = json.dumps(data, separators=(',', ':'))
response = requests.post(url, headers=headers, cookies=cookies, data=data)lis = []
json_data = response.json()['data']['content']
for li in json_data:country = li['countryCn']state = li['continentCn']total = li['sum']death_people = li['death']influence_people = li['population']found_lose = li['loss']dit = {'国家': country,'州': state,'总频次': total,'死亡人数': death_people,'影响人数': influence_people,'损失': found_lose}lis.append(dit)pd.DataFrame(lis).to_excel('global_disaster.xlsx',index=False)

数据清洗:

这里我们选择直接将缺失值删除

import pandas as pd# 读取文件
df = pd.read_excel('global_disaster.xlsx')# 将损失为缺失值的国家名字 展示出来
country_lose = df[df['损失'].isna()]['国家'].tolist()
# 删除缺失值
df.dropna(subset='损失', inplace=True)# 统计缺失值的数量
total = df['损失'].isna().sum()
# 展示处理后的前五条记录
print(df.head())


state_num = df['州'].unique()

没有不符合要求的命名
 


# iqr 处理异常值
lo = df['死亡人数'].quantile(0.25)
up = df['死亡人数'].quantile(0.75)
iqr = up - lo
lower = lo - 1.5 * iqr
upper = up + 1.5 * iqr# 未清理前的数据长度
before_clean = len(df)# df = df[(df['死亡人数'] > lower) & (df['死亡人数'] < upper)]
# 异常值 展示
# 异常值
false_death = df[(df['死亡人数'] < lower) | (df['死亡人数'] > upper)]
df['死亡人数'] = np.where((df['死亡人数'] < lower) | (df['死亡人数'] > upper),None,df['死亡人数']
)df.dropna(subset='死亡人数',inplace=True)print(len(df))# 思路是 将异常值用None值代替  后续删除

df['影响人数'] = pd.to_numeric(df['影响人数'], errors='coerce')
df['损失'] = pd.to_numeric(df['损失'], errors='coerce')
# print(df.info())
# print(df.head(5))


duplicated = df.duplicated().sum()
df.drop_duplicates(inplace=True)# print(len(df))

df['损失'] = (df['损失'] / 1000000).round(2)
print(df.head())


consistent_check = df[(df['总频次'] == 0) & (df['死亡人数'] > 0)]print(consistent_check)

数据可视化:

画出各州灾害总频次热力图  经济损失热力图  死亡人数热力图  平均灾害频次热力图

# 导包
import matplotlib.pyplot as plt
from matplotlib import rcParams
import seaborn as sns
import pandas as pddf = pd.read_excel('cleaned_global_disaster.xlsx')# 设置字体 为默认的黑体
rcParams['font.family'] = 'SimHei'region_summery = df.groupby(['州']).agg({'总频次': 'sum','死亡人数': 'sum','损失': 'sum','国家': 'count',
}).rename(columns={'国家': '国家数量', '损失': '损失(万元)'}).sort_values(by=['总频次', '损失(万元)'],ascending=[False, False])# 画子图
plt.subplot(2, 2, 1)
# annot = True  表示在热力图中显示对应的数值
# fmt = '.0f' 表示将数值类型的格式化为整数
# colormap的缩写 cmap   指定用红色系的颜色映射  Reds
# 设置cbar_Kws 用于设置颜色条的属性
# shrink 用于设置颜色条的大小
# annot_kws 用于设置注解的属性 字体 大小
# linewidths  设置单元格边框
sns.heatmap(region_summery[['总频次']], annot=True, fmt='.0f', cmap='Reds', linewidths=0.5,annot_kws={'size': 12, 'weight': 'bold'}, cbar_kws={'label': '灾害频次', 'shrink': 0.8})
plt.title('各州灾害总频次热力图')plt.subplot(2, 2, 2)
sns.heatmap(region_summery[['损失(万元)']],annot=True,annot_kws={'size': 12, 'weight': 'bold'},linewidths=0.5,fmt='.0f',cmap='Oranges',cbar_kws={'label': '损失(百万美元)', 'shrink': 0.8})plt.title('各州经济损失热力图')plt.subplot(2, 2, 3)
sns.heatmap(region_summery[['死亡人数']],annot=True,annot_kws={'size': 12, 'weight': 'bold'},linewidths=0.5,fmt='.0f',cmap='Purples',cbar_kws={'label': '死亡人数', 'shrink': 0.8})
plt.title('各州死亡人数热力图')plt.subplot(2, 2, 4)region_summery['平均频次'] = region_summery['总频次'] / region_summery['国家数量']
sns.heatmap(region_summery[['平均频次']],annot=True,annot_kws={'size': 12, 'weight': 'bold'},fmt='.1f',cmap='Blues',linewidths=0.5,cbar_kws={'label': '平均灾害频次', 'shrink': 0.8})
plt.title('各州平均灾害频次热力图')plt.tight_layout()
plt.show()
# print(region_summery)

如下图:

本次的案例分享到此结束 如果觉得还不错 你的点赞关注是我更新进步的动力 谢谢!

http://www.dtcms.com/a/531882.html

相关文章:

  • QT(c++)开发自学笔记:4.Qt 3D简易实现
  • Vue3 自定义事件
  • 上海住房和城乡建设厅网站个人备案网站可以做产品推广
  • Android OpenGLES视频剪辑示例源码
  • 做淘宝客导购网站推广wordpress 明星
  • WebForms 页面
  • Leetcode 39
  • 【STM32项目开源】基于STM32的智能水质检测系统
  • 设计模式-迭代器模式(Iterator)
  • GitHub等平台形成的开源文化正在重塑天热e
  • 做网站需要用什么开发软件有哪些制作视频的软件
  • github中获得Personal Access Token
  • 从RDPDD!DrvEscape到RDPWD!ShareClass::UPSendOrders
  • RiPro数据转换CeoMax插件
  • IA复习笔记4 路由
  • 邯郸手机网站建设服务常见的网络推广工具
  • NTRU 加密系统原理及示例:NTRU、CTRU以及ITRU
  • k8s高频面试题汇总
  • 一篇文章理解LRC校验:
  • 石家庄免费网站建设百度收录入口提交查询
  • 专业提供网站建设服务培训学校 网站费用
  • 找做网站公司需要注意什么条件国外网站建设什么价格
  • 阮一峰《TypeScript 教程》学习笔记——tsconfig.json 文件
  • python如何做声音识别
  • 解决Docker磁盘空间不足导致MySQL启动失败
  • 【微服务组件】Springboot结合Dubbo实现RPC调用
  • One-Shot Federated Learning with Classifier-FreeDiffusion Models
  • powershell终端在ide里默认位置不对
  • 探索Linux进程:从理论到实践
  • 正则化机制解析:L2 的约束逻辑与 L1 的特征选择