Python实战实现爬取天气数据并完成可视化分析详解


Posted in Python onJune 16, 2022

1.实现需求:

从网上(随便一个网址,我爬的网址会在评论区告诉大家,dddd)获取某一年的历史天气信息,包括每天最高气温、最低气温、天气状况、风向等,完成以下功能:

(1)将获取的数据信息存储到csv格式的文件中,文件命名为”城市名称.csv”,其中每行数据格式为“日期,最高温,最低温,天气,风向”;

(2)在数据中增加“平均温度”一列,其中:平均温度=(最高温+最低温)/2,在同一张图中绘制两个城市一年平均气温走势折线图;

(3)统计两个城市各类天气的天数,并绘制条形图进行对比,假设适合旅游的城市指数由多云天气占比0.3,晴天占比0.4,阴天数占比0.3,试比较两个城市中哪个城市更适合旅游;

(4)统计这两个城市每个月的平均气温,绘制折线图,并通过折线图分析该城市的哪个月最适合旅游;

(5)统计出这两个城市一年中,平均气温在18~25度,风力小于5级的天数,并假设该类天气数越多,城市就越适宜居住,判断哪个城市更适合居住;

爬虫代码:

import random
import time
from spider.data_storage import DataStorage
from spider.html_downloader import HtmlDownloader
from spider.html_parser import HtmlParser
class SpiderMain:
    def __init__(self):
        self.html_downloader=HtmlDownloader()
        self.html_parser=HtmlParser()
        self.data_storage=DataStorage()
    def start(self):
        """
        爬虫启动方法
        将获取的url使用下载器进行下载
        将html进行解析
        数据存取
        :return:
        """
        for i in range(1,13):  # 采用循环的方式进行依次爬取
            time.sleep(random.randint(0, 10))  # 随机睡眠0到40s防止ip被封
            url="XXXX"
            if i<10:
               url =url+"20210"+str(i)+".html"  # 拼接url
            else:
                url=url+"2021"+str(i)+".html"
            html=self.html_downloader.download(url)
            resultWeather=self.html_parser.parser(html)
            if i==1:
             t = ["日期", "最高气温", "最低气温", "天气", "风向"]
             resultWeather.insert(0,t)
            self.data_storage.storage(resultWeather)
if __name__=="__main__":
    main=SpiderMain()
    main.start()
import requests as requests
class HtmlDownloader:
    def download(self,url):
        """
        根据给定的url下载网页
        :param url:
        :return: 下载好的文本
        """
        headers = {"User-Agent":
                       "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0"}
        result = requests.get(url,headers=headers)
        return result.content.decode('utf-8')

此处大家需要注意,将User-Agent换成自己浏览器访问该网址的,具体如何查看呢,其实很简单,只需大家进入网站后,右键网页,然后点击检查将出现这样的界面:

Python实战实现爬取天气数据并完成可视化分析详解

然后只需再点击网络,再随便点击一个请求,如下图:

Python实战实现爬取天气数据并完成可视化分析详解

就可以进入如下图,然后再复制,图中User-Agent的内容就好了!

Python实战实现爬取天气数据并完成可视化分析详解

继续:

from bs4 import BeautifulSoup
class HtmlParser:
    def parser(self,html):
        """
        解析给定的html
        :param html:
        :return: area set
        """
        weather = []
        bs = BeautifulSoup(html, "html.parser")
        body = bs.body  # 获取html中的body部分
        div = body.find('div', {'class:', 'tian_three'})  # 获取class为tian_three的<div></div>
        ul = div.find('ul')  # 获取div中的<ul></ul>
        li = ul.find_all('li')  # 获取ul中的所有<li></li>
        for l in li:
            tempWeather = []
            div1 = l.find_all("div")  # 获取当前li中的所有div
            for i in div1:
                tempStr = i.string.replace("℃", "")  # 将℃进行替换
                tempStr = tempStr.replace(" ", "")  # 替换空格
                tempWeather.append(tempStr)
            weather.append(tempWeather)
        return weather
import pandas as pd
class DataStorage:
    def storage(self,weather):
        """
        数据存储
        :param weather list
        :return:
        """
        data = pd.DataFrame(columns=weather[0], data=weather[1:])  # 格式化数据
        data.to_csv("C:\\Users\\86183\\Desktop\\成都.csv", index=False, sep=",",mode="a")  # 保存到csv文件当中

注意,文件保存路径该成你们自己的哦!

ok,爬取代码就到这,接下来是图形化效果大致如下:

Python实战实现爬取天气数据并完成可视化分析详解

Python实战实现爬取天气数据并完成可视化分析详解

Python实战实现爬取天气数据并完成可视化分析详解

Python实战实现爬取天气数据并完成可视化分析详解

代码如下:

import pandas as pd
import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]  # 设置字体
plt.rcParams["axes.unicode_minus"] = False  # 该语句解决图像中的“-”负号的乱码问题
def broken_line_chart(x, y1, y2):  # 折线图绘制函数
    plt.figure(dpi=500, figsize=(10, 5))
    plt.title("泸州-成都每日平均气温折线图")
    plt.plot(x, y1, color='cyan', label='泸州')
    plt.plot(x, y2, color='yellow', label='成都')
    # 获取图的坐标信息
    coordinates = plt.gca()
    # 设置x轴每个刻度的间隔天数
    xLocator = mpl.ticker.MultipleLocator(30)
    coordinates.xaxis.set_major_locator(xLocator)
    # 将日期旋转30°
    plt.xticks(rotation=30)
    plt.xticks(fontsize=8)
    plt.ylabel("温度(℃)")
    plt.xlabel("日期")
    plt.legend()
    plt.savefig("平均气温走势折线图.png")  # 平均气温折线图
    plt.show()
    plt.close()
data_luZhou = pd.read_csv('C:\\Users\\86183\\Desktop\\泸州.csv')
data_chengdu = pd.read_csv('C:\\Users\\86183\\Desktop\\成都.csv')
# 将列的名称转为列表类型方便添加
columS = data_luZhou.columns.tolist()
columY = data_chengdu.columns.tolist()
# 将数据转换为列表
data_luZhou=np.array(data_luZhou).tolist()
data_chengdu=np.array(data_chengdu).tolist()
# 在最开始的位置上添加列的名字
data_luZhou.insert(0, columS)
data_chengdu.insert(0, columY)
# 添加平均气温列
data_luZhou[0].append("平均气温")
data_chengdu[0].append("平均气温")
weather_dict_luZhou = {}
weather_dict_chengdu = {}
for i in range(1, len(data_luZhou)):
    # 去除日期中的星期
    data_luZhou[i][0] = data_luZhou[i][0][0:10]
    data_chengdu[i][0] = data_chengdu[i][0][0:10]
    # 获取平均气温
    average_luZhou = int((int(data_luZhou[i][1]) + int(data_luZhou[i][2])) / 2)
    average_chengdu = int((int(data_chengdu[i][1]) + int(data_chengdu[i][2])) / 2)
    # 将平均气温添加进入列表中
    data_luZhou[i].append(average_luZhou)
    data_chengdu[i].append(average_chengdu)
# 将新的数据存入新的csv中
new_data_luZhou = pd.DataFrame(columns=data_luZhou[0], data=data_luZhou[1:])
new_data_chengdu = pd.DataFrame(columns=data_chengdu[0], data=data_chengdu[1:])
new_data_luZhou.to_csv("D:/PythonProject/spider/泸州.csv", index=False, sep=",")
new_data_chengdu.to_csv("D:/PythonProject/spider/成都.csv", index=False, sep=",")
# 折线图的绘制
y1 = np.array(new_data_luZhou.get("平均气温")).tolist()
y2 = np.array(new_data_chengdu.get("平均气温")).tolist()
x = np.array(new_data_luZhou.get("日期")).tolist()
broken_line_chart(x, y1, y2)
# 进行每个月的平均气温求解
new_data_luZhou["日期"] = pd.to_datetime(new_data_luZhou["日期"])
new_data_chengdu["日期"] = pd.to_datetime(new_data_chengdu["日期"])
new_data_luZhou.set_index("日期", inplace=True)
new_data_chengdu.set_index("日期", inplace=True)
# 按月进行平均气温的求取
month_l = new_data_luZhou.resample('m').mean()
month_l = np.array(month_l).tolist()
month_c = new_data_chengdu.resample('m').mean()
month_c = np.array(month_c).tolist()
length = len(month_c)
month_average_l = []
month_average_c = []
for i in range(length):
    month_average_l.append(month_l[i][2])
    month_average_c.append(month_c[i][2])
month_list = [str(i) + "月" for i in range(1, 13)]
plt.figure(dpi=500, figsize=(10, 5))
plt.title("泸州-成都每月平均折线气温图")
plt.plot(month_list, month_average_l, color="cyan",label="泸州", marker='o')
plt.plot(month_list, month_average_c, color="blue",label='成都', marker='v')
for a, b in zip(month_list, month_average_l):
    plt.text(a, b + 0.5, '%.2f' % b, horizontalalignment='center', verticalalignment='bottom', fontsize=6)
for a, b in zip(month_list, month_average_c):
    plt.text(a, b - 0.5, '%.2f' % b, horizontalalignment='center', verticalalignment='bottom', fontsize=6)
plt.legend()
plt.xlabel("月份")
plt.ylabel("温度(℃)")
plt.savefig("月平均气温折线图.png")  # 月平均气温折线图
plt.show()
#
# 只获取两列的数据
data_l = pd.read_csv("泸州.csv", usecols=['风向', '平均气温'])
data_c = pd.read_csv("成都.csv", usecols=['风向', '平均气温'])
data_l = np.array(data_l).tolist()
data_c = np.array(data_c).tolist()
day_c = 0
day_l = 0
for i in range(len(data_l)):
    if len(data_l[i][0]) == 5:
        if int(data_l[i][0][3]) < 5 and 18 <= int(data_l[i][1]) <= 25:
            day_l += 1
    else:
        if int(data_l[i][0][2]) < 5 and 18 <= int(data_l[i][1]) <= 25:
            day_l += 1
    if len(data_c[i][0]) == 5:
        if int(data_c[i][0][3]) < 5 and 10 <= int(data_c[i][1]) <= 25:
            day_c += 1
    else:
        if int(data_c[i][0][2]) < 5 and 18 <= int(data_c[i][1]) <= 25:
            day_c += 1
plt.figure(dpi=500, figsize=(8, 4))
plt.title("泸州-成都平均气温在18-25且风力<5级的天数")
list_name = ['泸州', '成都']
list_days = [day_l, day_c]
plt.bar(list_name, list_days, width=0.5)
plt.text(0, day_l, '%.0f' % day_l, horizontalalignment='center', verticalalignment='bottom', fontsize=7)
plt.text(1, day_c, '%.0f' % day_c, horizontalalignment='center', verticalalignment='bottom', fontsize=7)
plt.xlabel("城市")
plt.ylabel("天数(d)")
plt.savefig("适宜居住柱形图.png")
plt.show()
data_l=pd.read_csv("泸州.csv")
data_c=pd.read_csv("成都.csv")
# 将数据转换为列表
data_l=np.array(data_l).tolist()
data_c=np.array(data_c).tolist()
# 获取每种天气的天数,采用字典类型进行存储
for i in range(1,365):
    weather_l = data_l[i][3]
    weather_c = data_c[i][3]
    if weather_l in weather_dict_luZhou:
       weather_dict_luZhou[weather_l] = weather_dict_luZhou.get(weather_l) + 1
    else:
       weather_dict_luZhou[weather_l]=1
    if weather_c in weather_dict_chengdu:
        weather_dict_chengdu[weather_c]=weather_dict_chengdu.get(weather_c)+1
    else:
       weather_dict_chengdu[weather_c]=1
weather_list_luZhou = list(weather_dict_luZhou)
weather_list_chengdu = list(weather_dict_chengdu)
value_l = []
value_c = []
# 获取所有的天气种类
weather_list = sorted(set(weather_list_luZhou + weather_list_chengdu))
# 获取每种天气的天数,并将其对应的放入列表中,没有的则用0进行替代,方便条形图的绘制。
for i in weather_list:
    if i in weather_dict_luZhou:
        value_l.append(weather_dict_luZhou[i])
    else:
        value_l.append(0)
    if i in weather_dict_chengdu:
        value_c.append(weather_dict_chengdu[i])
    else:
        value_c.append(0)
# 绘制条形图进行对比
plt.figure(dpi=500, figsize=(10, 5))
plt.title("泸州-成都各种天气情况对比")
x1 = list(range(len(weather_list)))
x = [i + 0.4 for i in x1]
plt.bar(x1, value_l, width=0.4, color='red', label='泸州')
plt.bar(x, value_c, width=0.4, color='orange', label='成都')
for a, b in zip(x1, value_l):
    plt.text(a, b + 0.4, '%.0f' % b, ha='center', va='bottom', fontsize=7)
for a, b in zip(x, value_c):
    plt.text(a, b + 0.4, '%.0f' % b, ha='center', va='bottom', fontsize=7)
plt.xticks(x1, weather_list)
plt.ylabel("天数")
plt.xlabel("天气")
plt.xticks(rotation=270)
plt.legend()
plt.savefig("泸州成都天气情况对比.png")
plt.show()
plt.close()

好的这次就到这儿吧,我们下次见哦!!!

到此这篇关于Python实战实现爬取天气数据并完成可视化分析详解的文章就介绍到这了,更多相关Python爬取天气数据内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python迭代器和生成器介绍
Mar 06 Python
python实现通过pil模块对图片格式进行转换的方法
Mar 24 Python
Python常见格式化字符串方法小结【百分号与format方法】
Sep 18 Python
Python、PyCharm安装及使用方法(Mac版)详解
Apr 28 Python
python实现对excel进行数据剔除操作实例
Dec 07 Python
解决tensorflow模型参数保存和加载的问题
Jul 26 Python
Pycharm之快速定位到某行快捷键的方法
Jan 20 Python
python selenium 查找隐藏元素 自动播放视频功能
Jul 24 Python
解决Python设置函数调用超时,进程卡住的问题
Aug 08 Python
在 Python 中接管键盘中断信号的实现方法
Feb 04 Python
使用Keras预训练模型ResNet50进行图像分类方式
May 23 Python
Python使用pandas导入xlsx格式的excel文件内容操作代码
Dec 24 Python
pandas时间序列之pd.to_datetime()的实现
Jun 16 #Python
pandas中pd.groupby()的用法详解
Jun 16 #Python
python中pd.cut()与pd.qcut()的对比及示例
Jun 16 #Python
Python自动操作神器PyAutoGUI的使用教程
Jun 16 #Python
python内置模块之上下文管理contextlib
Jun 14 #Python
Python时间操作之pytz模块使用详解
Django框架之路由用法
Jun 10 #Python
You might like
Windows下XDebug 手工配置与使用说明
2010/07/11 PHP
PHP循环结构实例讲解
2014/02/10 PHP
php目录操作实例代码
2014/02/21 PHP
PHP使用GIFEncoder类处理gif图片实例
2014/07/01 PHP
编写PHP脚本清除WordPress头部冗余代码的方法讲解
2016/03/01 PHP
Yii2 rbac权限控制之rule教程详解
2016/06/23 PHP
jQuery 使用手册(五)
2009/09/23 Javascript
javascript getElementsByTagName
2011/01/31 Javascript
js 链式延迟执行DOME
2012/01/04 Javascript
jQuery文本框(input textare)事件绑定方法教程
2013/04/24 Javascript
JavaScript中的6种运算符总结
2014/10/16 Javascript
JQuery替换DOM节点的方法
2015/06/11 Javascript
jquery attr()设置和获取属性值实例教程
2016/09/25 Javascript
详解vue 组件之间使用eventbus传值
2017/10/25 Javascript
js实现搜索栏效果
2018/11/16 Javascript
详解使用JWT实现单点登录(完全跨域方案)
2019/08/02 Javascript
浅谈vue单页面中有多个echarts图表时的公用代码写法
2020/07/19 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS TNC
2018/03/30 DOTA
Python查看多台服务器进程的脚本分享
2014/06/11 Python
Python迭代用法实例教程
2014/09/08 Python
python计算牛顿迭代多项式实例分析
2015/05/07 Python
Python编程中NotImplementedError的使用方法
2018/04/21 Python
python3实现字符串的全排列的方法(无重复字符)
2018/07/07 Python
Django实现表单验证
2018/09/08 Python
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
2019/07/31 Python
python mysql 字段与关键字冲突的解决方式
2020/03/02 Python
django API 中接口的互相调用实例
2020/04/01 Python
使用iframe+postMessage实现页面跨域通信的示例代码
2020/01/14 HTML / CSS
Interhome丹麦:在线预订度假屋和公寓
2019/07/18 全球购物
旅行社各个岗位职责
2014/03/15 职场文书
故意伤害人身损害赔偿协议书
2014/11/19 职场文书
优秀大学生事迹材料
2014/12/24 职场文书
乡镇法制宣传日活动总结
2015/05/05 职场文书
MySQL下使用Inplace和Online方式创建索引的教程
2021/05/26 MySQL
SpringBoot整合RabbitMQ的5种模式实战
2021/08/02 Java/Android
一次SQL如何查重及去重的实战记录
2022/03/13 MySQL