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

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

|----------------|-------------|
| requests() | lxml |
| pandas | numpy |
| matplotlib | seaborn |
| pprint | |
[本案例所使用的库]

明确需要爬取的内容:

国家地区

所属洲

总频次

受影响人口(万人)

死亡人口(人)

经济损失(千美元)

爬取步骤:

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

解析数据 提取想要的数据

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

一.发送请求

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

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

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

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

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

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

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

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

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

复制右边的代码 到Pycharm中

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

二. 解析数据

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

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

python 复制代码
import pprint


pprint.pprint(response.json())

这样输出就会如下图所示

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

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

python 复制代码
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文件

python 复制代码
# 先将数据存储到 字典中
# 再定义一个列表  将数据添加进去
dit = {
        '国家': country,
        '州': state,
        '总频次': total,
        '死亡人数': death_people,
        '影响人数': influence_people,
        '损失': found_lose
    }

# 保存数据 为excel
pd.DataFrame(lis).to_excel('global_disaster.xlsx',index=False)

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

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

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

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

python 复制代码
import pprint

import pandas as pd
import requests
import json

headers = {
    "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)

数据清洗:

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

python 复制代码
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())

python 复制代码
state_num = df['州'].unique()

没有不符合要求的命名


python 复制代码
# 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值代替  后续删除

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


python 复制代码
duplicated = df.duplicated().sum()
df.drop_duplicates(inplace=True)

# print(len(df))

python 复制代码
df['损失'] = (df['损失'] / 1000000).round(2)
print(df.head())


python 复制代码
consistent_check = df[(df['总频次'] == 0) & (df['死亡人数'] > 0)]

print(consistent_check)

数据可视化:

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

python 复制代码
# 导包
import matplotlib.pyplot as plt
from matplotlib import rcParams
import seaborn as sns
import pandas as pd

df = 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)

如下图:

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

相关推荐
B站计算机毕业设计之家3 小时前
计算机视觉:YOLO实现目标识别+目标跟踪技术 pyqt界面 OpenCV 计算机视觉 深度学习 计算机(建议收藏)✅
python·opencv·yolo·计算机视觉·目标跟踪·口罩识别
AI小云4 小时前
【Python高级编程】类属性与类方法
人工智能·python
B站计算机毕业设计之家5 小时前
深度学习:YOLOv8人体行为动作识别检测系统 行为识别检测识系统 act-dataset数据集 pyqt5 机器学习✅
人工智能·python·深度学习·qt·yolo·机器学习·计算机视觉
青云交5 小时前
Java 大视界 -- Java 大数据在智能建筑能耗监测与节能策略制定中的应用
数据分析·数据存储·数据可视化·1024程序员节·能耗监测·java 大数据·智能建筑
墨利昂5 小时前
Pytorch常用API(ML和DL)
人工智能·pytorch·python
SunnyDays10115 小时前
Python 裁剪 PDF 教程:轻松裁剪页面并导出为图片
python·pdf裁剪·裁剪pdf页面·裁切pdf
JustNow_Man5 小时前
Cline插件中clinerules的选择机制
python
2401_841495646 小时前
【自然语言处理】Transformer模型
人工智能·python·深度学习·算法·语言模型·自然语言处理·transformer
m0_748233646 小时前
C++与Python:内存管理与指针的对比
java·c++·python