【python爬虫+数分+可视化】基于广州近年天气数据

共 6395字,需浏览 13分钟

 ·

2021-12-26 03:38

今天给大家带来的是python数据分析的全流程实战

首先通过爬虫技术获取数据,然后通过pandas清洗和分析数据,最后通过pyecharts进行数据的可视化。这次的爬虫采用的是蚂蚁老师课程介绍的selenium相关技术,它的操作相比于request来说,更贴切人工使用浏览器访问网站的模式,可以绕开复杂的js分析,直接获取数据,所以强烈推荐大家学习蚂蚁老师的selenium爬虫课程!

下面正式开始介绍本次的实战步骤

一:通过selenium爬虫获取数据

本次获取的数据是广州的2019-2021年各月的历史数据

http://www.tianqihoubao.com/lishi/guangzhou/month/202010.html

例如这个url,里面就有广州2020年10月的天气数据

本次的爬虫用到了selenium库,运行前需要安装selenium的库以及用于驱动浏览器的应用程序

我的驱动程序在C:/WebDriver/bin/msedgedriver.exe这个位置。

from selenium.webdriver import Edge
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
import time

driver = Edge(executable_path="C:/WebDriver/bin/msedgedriver.exe")

driver.get("https://tianqi.2345.com/wea_history/59287.htm")

# 网页每次加载1个月份的数据,36次循环,就是爬取19-21三年的数据
for i in range(36):
    # 确保网页加载完成
    WebDriverWait(driver, 10).until(lambda d: "广州历史天气" in d.title)
    content = driver.find_element(By.XPATH, '//*[@id="weather-history"]/table/tbody').text
    with open(f"guangzhou/{i}.csv""w", encoding='utf-8') as fin:
        fin.write(content)
    # 休眠确保数据加载完成
    time.sleep(1)
    driver.find_element(By.XPATH, '//*[@id="js_prevMonth"]').click()
    time.sleep(1)

二:通过pandas进行数据清洗

import pandas as pd
import numpy as np
# 读取刚才爬取保存在csv文件里的数据,然后加载到pandas的dataframe的结构里
df_list = []

for i in range(36):
    data = pd.read_csv(f"guangzhou/{i}.csv", sep=' ')
    df_list.append(data)
df_all = pd.concat(df_list)

查看一下拼接后的数据是什么样子的

df_all


日期最高温最低温天气风力风向空气质量指数
2021-12-01周三20°多云~晴北风3级46
2021-12-02周四21°多云~晴北风3级47
2021-12-03周五22°多云~晴东北风3级48
2021-12-04周六22°多云~晴东北风2级45
2021-12-05周日22°多云~晴东北风2级52
........................
2019-01-27周日23°11°东北风2级81
2019-01-28周一23°11°多云~晴东南风2级88
2019-01-29周二24°13°东南风1级82
2019-01-30周三25°15°多云~阴东南风2级55
2019-01-31周四24°12°多云~阴东北风2级46

1083 rows × 6 columns

发现列名都错位了

我们先重置一下索引,然后再对列名进行修正

df_all = df_all.reset_index()
df_all

level_0level_1日期最高温最低温天气风力风向空气质量指数
02021-12-01周三20°多云~晴北风3级46
12021-12-02周四21°多云~晴北风3级47
22021-12-03周五22°多云~晴东北风3级48
32021-12-04周六22°多云~晴东北风2级45
42021-12-05周日22°多云~晴东北风2级52
...........................
10782019-01-27周日23°11°东北风2级81
10792019-01-28周一23°11°多云~晴东南风2级88
10802019-01-29周二24°13°东南风1级82
10812019-01-30周三25°15°多云~阴东南风2级55
10822019-01-31周四24°12°多云~阴东北风2级46

1083 rows × 8 columns

df_all.columns = ["日期","星期","最高气温","最低气温","天气","风力风向","空气质量指数","空气质量评级"]
df_all["日期"] = pd.to_datetime(df_all["日期"])df_all.set_index("日期", inplace=True)df_all

星期最高气温最低气温天气风力风向空气质量指数空气质量评级
日期






2021-12-01周三20°多云~晴北风3级46
2021-12-02周四21°多云~晴北风3级47
2021-12-03周五22°多云~晴东北风3级48
2021-12-04周六22°多云~晴东北风2级45
2021-12-05周日22°多云~晴东北风2级52
........................
2019-01-27周日23°11°东北风2级81
2019-01-28周一23°11°多云~晴东南风2级88
2019-01-29周二24°13°东南风1级82
2019-01-30周三25°15°多云~阴东南风2级55
2019-01-31周四24°12°多云~阴东北风2级46

1083 rows × 7 columns

将气温列的数据转为数字

df_all["最高气温"] = df_all["最高气温"].str.replace("°""")
df_all["最低气温"] = df_all["最低气温"].str.replace("°""")

将风向和风力分离

首先对"风力风向"一列按"风"分割转换为列表,然后将得到的列表转置,最后复制给新增的"风向"、"风力"两列

temp = df_all["风力风向"].str.split("风").to_list()temp
[['北''3级'],
 ['北''3级'],
 ['东北''3级'],
 ['东北''2级'],
 ['东北''2级'],
 ['东北''3级'],
 ['东北''2级'],
 ['东北''2级'],
 ['东北''2级'],
 ['东北''2级'],
 ['东北''1级'],
 ['北''3级'],
 ['北''3级'],
 ['东北''2级'],
 ['东''1级'],
 ['东北''1级'],
 ['北''4级'],
 ['东北''3级'],
 ['东北''2级'],
 ['东北''2级'],
 ['东北''2级'],
 ['东南''1级'],
 ['东南''2级'],
 ['东南''2级'],
 ['东南''2级'],
 ['北''4级'],
 ['北''3级'],
 ['北''3级'],
 ['东北''2级'],
 ...]
# 转置
temp = list(map(list, zip(*temp)))
df_all["风向"] = temp[0]
df_all["风力"] = temp[1]
# 这就是最终清洗好的数据
df_all

星期最高气温最低气温天气风力风向空气质量指数空气质量评级风向风力
日期








2021-12-01周三207多云~晴北风3级463级
2021-12-02周四217多云~晴北风3级473级
2021-12-03周五227多云~晴东北风3级48东北3级
2021-12-04周六227多云~晴东北风2级45东北2级
2021-12-05周日228多云~晴东北风2级52东北2级
..............................
2019-01-27周日2311东北风2级81东北2级
2019-01-28周一2311多云~晴东南风2级88东南2级
2019-01-29周二2413东南风1级82东南1级
2019-01-30周三2515多云~阴东南风2级55东南2级
2019-01-31周四2412多云~阴东北风2级46东北2级

1083 rows × 9 columns

三:利用pyechats对数据进行可视化并且分析

from pyecharts import options as opts
from pyecharts.charts import Pie
from pyecharts.charts import Line

1.绘制饼图查看天气类型对比

df_all_tianqi = df_all.groupby("天气").size().sort_values(ascending=False)
df_all_tianqi
天气
多云          216
阴~多云        146
晴            83
多云~晴         73
阴~雷阵雨        55
           ... 
中到大雨~雷阵雨      1
大雨~多云         1
多云~阵雨         1
中雨~晴          1
雾~多云          1
Length: 63, dtype: int64
def create_pie(datas, title) -> Pie:
    """ 创建饼图对象
    文档地址:https://pyecharts.org/#/zh-cn/basic_charts?id=pie%ef%bc%9a%e9%a5%bc%e5%9b%be
    @param datas: 数据,形式为[('晴', 115), ('多云', 78), ('晴~多云', 39)]
    @param title: 图表的标题
    "
""
    pie = Pie()
    pie.add("", datas)
    pie.set_global_opts(
        title_opts=opts.TitleOpts(title=title),
        legend_opts=opts.LegendOpts(pos_right="right")
    )
    pie.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}: {d}%"))
    return pie
datas = list(zip(df_all_tianqi.index.to_list(), df_all_tianqi.to_list()))
datas
[('多云', 216),
 ('阴~多云', 146),
 ('晴', 83),
 ('多云~晴', 73),
 ('阴~雷阵雨', 55),
 ('雷阵雨', 47),
 ('中雨~雷阵雨', 37),
 ('小雨', 31),
 ('晴~多云', 30),
 ('阴', 29),
 ('阴~阵雨', 21),
 ('雷阵雨~多云', 20),
 ('多云~雷阵雨', 19),
 ('多云~小雨', 19),
 ('小雨~雷阵雨', 18),
 ('阴~小雨', 17),
 ('阴~中雨', 15),
 ('大雨~雷阵雨', 15),
 ('小雨~多云', 14),
 ('多云~阴', 14),
 ('阴~晴', 14),
 ('中雨', 14),
 ('小雨~中雨', 12),
 ('大雨~中雨', 11),
 ('阴~大雨', 9),
 ('雷阵雨~中雨', 8),
 ('小雨~阵雨', 7),
 ('大雨', 7),
 ('中雨~多云', 6),
 ('小雨~大雨', 6),
 ('小雨~晴', 5),
 ('中雨~大雨', 5),
 ('中雨~小雨', 4),
 ('中雨~暴雨', 4),
 ('多云~中雨', 4),
 ('暴雨~雷阵雨', 3),
 ('阵雨~小雨', 3),
 ('大雨~阵雨', 3),
 ('小雨~阴', 3),
 ('暴雨~中雨', 2),
 ('暴雨~大雨', 2),
 ('晴~小雨', 2),
 ('雷阵雨~小雨', 2),
 ('雷阵雨~大雨', 2),
 ('中雨~阵雨', 2),
 ('中雨~阴', 2),
 ('大雨~小雨', 2),
 ('雷阵雨~阴', 2),
 ('阴~暴雨', 2),
 ('大雨~阴', 2),
 ('阵雨~阴', 2),
 ('雷阵雨~中到大雨', 1),
 ('阵雨~雷阵雨', 1),
 ('中到大雨~中雨', 1),
 ('阵雨~中雨', 1),
 ('阵雨', 1),
 ('晴~雷阵雨', 1),
 ('晴~阴', 1),
 ('中到大雨~雷阵雨', 1),
 ('大雨~多云', 1),
 ('多云~阵雨', 1),
 ('中雨~晴', 1),
 ('雾~多云', 1)]
pie = create_pie(datas, "饼图-天气对比")
pie.render_notebook()
    "2d6ef13045b646dc9a47240b506c0637" style="width:900px; height:500px;">

可以发现广州的天气以多云为主

2.绘制饼图查看风向数据比例对比

fengxiang = df_all.groupby("风向").size().sort_values(ascending=False)
datas = list(zip(fengxiang.index.to_list(), fengxiang.to_list()))
pie = create_pie(datas, "饼图-风向")
pie.render_notebook()
    "8dd16bd33b9744568abe5e686b2c1579" style="width:900px; height:500px;">

可以发现广州的风向以东南、东北以及西南为主

3.绘制饼图查看空气质量对比

aqiInfo = df_all.groupby("空气质量评级").size().sort_values(ascending=False)
datas = list(zip(aqiInfo.index.to_list(), aqiInfo.to_list()))
pie = create_pie(datas, "饼图-空气质量")
pie.render_notebook()
    "9ea8ccaf72a5484d8f14b10ecf5ab288" style="width:900px; height:500px;">

可以发现广州的空气质量还不错,优占了一大半。绝大部分都在良以上


最后,推荐蚂蚁老师的《零基础入门Python数据分析到办公自动化》课程:



浏览 69
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报