使用Python爬取天气数据并制作天气预报对话框

背景:

考试周突然布置python大作业,本来打算网上找现成的拼接一下,但是要不然相同需求的要掏50块钱,要不然太过专业,一看就不是学生几天之内能完成的。于是打算自己做一个。

任务需求:

基于python语言实现天气预报系统设计 
(1)系统必须是界面操作方法,界面友好;
(2)系统能够选择天气预报的城市;
(3)系统能够显示至少七天的天气数据;
(4)系统能够显示温度范围、风力、雨雪等天气情况;
(5)系统能够对每个城市的温度、风力等情况进行统计分析;
(6)系统能够对每个城市的温度、风力等情况进行随时间变化多种图形显示;
(7)系统能够将天气信息进行保存处理。

我自己加了两个小功能:
(8)利用现有的tcl脚本,实现界面的美化,模拟win11画风
(9)添加一键切换暗夜模式

效果演示:

开机界面:

7天模式与折线图:

 15天模式与统计图:

 暗夜模式:

 爬取到的未来15天天气:

代码实现:

1、爬取未来15天天气

由于题干要求天气数据包括风力,而主流天气网站中,15天的预告往往不包括风力,或者15天拆分成1-7与8-15进行详细播报。
因此这里我们分别爬取了1-7天的天气网天气数据和8-15天的天气网天气数据,加到一个列表中,以实现日期,星期,天气情况,最低气温,最高气温,风级的数据爬取,能够输出为7天的csv和15天的csv文件。

这一部分的代码是更改的现有的天气爬取代码,展示如下:

import requests
from bs4 import BeautifulSoup
import csv
import os


def getHTMLtext(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        print("成功访问")
        return r.text
    except:
        print("访问错误")
        return " "


def get_content(html):
    final = []  # 初始化一个列表保存数据
    bs = BeautifulSoup(html, "html.parser")  # 创建BeautifulSoup对象
    body = bs.body
    data = body.find('div', {'id': '7d'})  # 找到div标签且id = 7d

    # 下面爬取7天的数据
    ul = data.find('ul')  # 找到所有的ul标签
    li = ul.find_all('li')  # 找到左右的li标签
    i = 0  # 控制爬取的天数
    for day in li:  # 遍历找到的每一个li
        if 7 > i >= 0:
            temp = []  # 临时存放每天的数据

            date = day.find('h1').string  # 得到日期
            date1 = date[0:date.index('(')]
            temp.append(date1)

            week = date[date.index('(')+1:date.index(')')]  # 得到星期
            temp.append(week)

            inf = day.find_all('p')  # 找出li下面的p标签,提取第一个p标签的值,即天气
            wea = inf[0].string
            if '转' in wea:
                wea = wea[0:wea.index('转')]
            temp.append(wea)

            tem_low = inf[1].find('i').string  # 找到最低气温
            temp.append(tem_low[:-1])

            if inf[1].find('span') is None:  # 天气预报可能没有最高气温
                tem_high = None
                temp.append(tem_high)
            else:
                tem_high = inf[1].find('span').string  # 找到最高气温
                if tem_high[-1] == '℃':
                    temp.append(tem_high[:-1])
                else:
                    temp.append(tem_high)

            wind_scale = inf[2].find('i').string  # 找到风级
            wind = wind_scale[0:wind_scale.index('级')]
            temp.append(wind)

            final.append(temp)
        i = i + 1
    return final


def get_content2(html):
    final = []  # 初始化一个列表保存数据
    bs = BeautifulSoup(html, "html.parser")  # 创建BeautifulSoup对象
    body = bs.body
    data = body.find('div', {'id': '15d'})  # 找到div标签且id = 15d
    ul = data.find('ul')  # 找到所有的ul标签
    li = ul.find_all('li')  # 找到左右的li标签
    i = 0  # 控制爬取的天数
    for day in li:  # 遍历找到的每一个li
        if i < 8:
            temp = []  # 临时存放每天的数据
            date = day.find('span', {'class': 'time'}).string  # 得到日期

            date1 = date[date.index('(') + 1:-1]  # 取出日期号
            temp.append(date1)

            week = date[0:date.index('(')]
            temp.append(week)

            weather = day.find('span', {'class': 'wea'}).string  # 找到天气
            if '转' in weather:
                weather = weather[0:weather.index('转')]
            temp.append(weather)

            tem = day.find('span', {'class': 'tem'}).text  # 找到温度
            temp.append(tem[tem.index('/') + 1:-1])  # 找到最低气温
            temp.append(tem[:tem.index('/') - 1])  # 找到最高气温

            wind_scale = day.find('span', {'class': 'wind1'}).string  # 找到风级
            wind = wind_scale[0:wind_scale.index('级')]
            temp.append(wind)

            final.append(temp)
    return final


def write_to_csv(file_name, data):
    with open(file_name, 'a', errors='ignore', newline='') as f:
        header = ['日期', '星期', '天气', '最低气温', '最高气温', '风级']
        f_csv = csv.writer(f)
        f_csv.writerow(header)
        f_csv.writerows(data)


def main(city):
    if city == '西安':
        erea = '101110101'
    if city == '武汉':
        erea = '101200101'
    if city == '深圳':
        erea = '101280601'
    if city == '上海':
        erea = '101020100'
    if city == '哈尔滨':
        erea = '101050101'

    url1 = 'http://www.weather.com.cn/weather/' + erea + '.shtml'  # 7天天气中国天气网
    url2 = 'http://www.weather.com.cn/weather15d/' + erea + '.shtml'  # 8-15天天气中国天气网

    html1 = getHTMLtext(url1)
    data1_7 = get_content(html1)  # 获得1-7天和当天的数据

    html2 = getHTMLtext(url2)
    data8_15 = get_content2(html2)  # 获得8-15天数据

    data15 = data1_7 + data8_15

    if os.path.isfile("weather15.csv"):   # 检查文件是否存在
        os.remove("weather15.csv")        # 删除文件

    if os.path.isfile("weather7.csv"):   # 检查文件是否存在
        os.remove("weather7.csv")        # 删除文件

    write_to_csv('weather7.csv', data1_7)  # 保存为csv文件
    write_to_csv('weather15.csv', data15)  # 保存为csv文件

注意这一部分代码只是定义了五个函数,用于主py文件的调用,并不能独立运行。并且这里的输入变量是城市名,我写的这个只支持西安、武汉、深圳、上海、哈尔滨,可以自行增加城市id。

2、建立选项对话框

选项对话框主要用于设置城市或日期模式,时用tkinter库定义并放置即可,代码如下:

​# 选项栏显示
def xuanxianglan():
    global var_4, var_6
    option_city_list = ["城市", "西安", "武汉", "深圳", "上海", "哈尔滨"]
    option_mode_list = ["模式", "7天", "15天"]
    var_4 = tk.StringVar(value=option_city_list[1])  # 存储城市
    var_6 = tk.StringVar(value=option_mode_list[1])

    # 创建一个框架!!!!!!!
    check_frame = ttk.LabelFrame(frame1, text="选项", padding=(20, 10))
    check_frame.grid(row=0, column=0, padx=(20, 10), pady=(20, 10), sticky="nw")

    # 创建选择列表选择城市
    optionmenucity = ttk.OptionMenu(check_frame, var_4, *option_city_list)
    optionmenucity.grid(row=0, column=0, padx=5, pady=10, sticky="nsew")

    # 创建选择列表选择模式
    optionmenumode = ttk.OptionMenu(check_frame, var_6, *option_mode_list)
    optionmenumode.grid(row=1, column=0, padx=5, pady=10, sticky="nsew")

    # 创建按钮切换统计图
    button = ttk.Button(check_frame, text="统计图")
    button.grid(row=2, column=0, padx=5, pady=10, sticky="nsew")
    button.config(command=get_statistic)

    # 创建按钮切换折线图
    button1 = ttk.Button(check_frame, text="折线图")
    button1.grid(row=3, column=0, padx=5, pady=10, sticky="nsew")
    button1.config(command=get_line_chart)

    var_1 = tk.StringVar()

    def callCheckbutton():
        if var_1.get() == '1':
            root.tk.call("set_theme", "dark")
        else:
            root.tk.call("set_theme", "light")

    # Switch来切换暗夜模式
    switchdark = ttk.Checkbutton(check_frame, variable=var_1, text="Dark", style="Switch.TCheckbutton",
                                 command=callCheckbutton)
    switchdark.grid(row=4, column=0, padx=5, pady=10, sticky="nsew")

3、建立天气情况显示栏

这里分为7天的模式和15天的模式,以建立不同的显示栏。7天有7个LabelFrame组件,7个需排列成一排,并且7天模式支持图像显示天气;15天模式将15个LabelFrame组件5×3排列。

七天的代码如下:

# 7天的天气栏显示
def tianqilan7():
    global day16_frame, day17_frame, day18_frame, day19_frame, day20_frame, day21_frame, day22_frame
    global tianqi7flag

    jiazaitubiao()
    tianqi7flag = 1

    # 创建第一天天气框架!!!!!
    day16_frame = ttk.LabelFrame(frame1, text='今天'.format(df['星期'][0]), padding=(20, 10))
    day16_frame.grid(row=0, column=1, padx=0, pady=(20, 10), sticky="nsw")
    # 先插一张图片
    tianqi_img16 = tk.Label(day16_frame, image=ifphoto(df['天气'][0]))
    tianqi_img16.grid(row=0, column=0)
    # 再插一个大文本
    word1 = tk.Label(day16_frame,
                     text='\n{}\n'.format(df['天气'][0]),
                     font=('仿宋', 22),
                     padx=0,
                     pady=0)
    word1.grid(row=1, column=0, padx=5, pady=0, sticky="s")
    # 再插几行小文本
    word2 = tk.Label(day16_frame,
                     text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][0], df['最高气温'][0], df['风级'][0],
                                                      df['日期'][0]),
                     font=('微软雅黑', 10),
                     padx=0,
                     pady=0)
    word2.grid(row=2, column=0, padx=5, pady=0, sticky="s")

    # 创建第二天天气框架!!!!!
    day17_frame = ttk.LabelFrame(frame1, text='明天'.format(df['星期'][1]), padding=(20, 10))
    day17_frame.grid(row=0, column=2, padx=3, pady=(20, 10), sticky="ns")
    # 先插一张图片
    tianqi_img17 = tk.Label(day17_frame, image=ifphoto(df['天气'][1]))
    tianqi_img17.grid(row=0, column=0)
    # 再插一个大文本
    word3 = tk.Label(day17_frame,
                     text='\n{}\n'.format(df['天气'][1]),
                     font=('仿宋', 22),
                     padx=0,
                     pady=0)
    word3.grid(row=1, column=0, padx=5, pady=0, sticky="s")
    # 再插几行小文本
    word4 = tk.Label(day17_frame,
                     text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][1], df['最高气温'][1], df['风级'][1],
                                                      df['日期'][1]),
                     font=('微软雅黑', 10),
                     padx=0,
                     pady=0)
    word4.grid(row=2, column=0, padx=5, pady=0, sticky="s")

    # 创建第三天天气框架!!!!!
    day18_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][2]), padding=(20, 10))
    day18_frame.grid(row=0, column=3, padx=0, pady=(20, 10), sticky="nsw")
    # 先插一张图片
    tianqi_img18 = tk.Label(day18_frame, image=ifphoto(df['天气'][2]))
    tianqi_img18.grid(row=0, column=0)
    # 再插一个大文本
    word5 = tk.Label(day18_frame,
                     text='\n{}\n'.format(df['天气'][2]),
                     font=('仿宋', 22),
                     padx=0,
                     pady=0)
    word5.grid(row=1, column=0, padx=5, pady=0, sticky="s")
    # 再插几行小文本
    word6 = tk.Label(day18_frame,
                     text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][2], df['最高气温'][2], df['风级'][2],
                                                      df['日期'][2]),
                     font=('微软雅黑', 10),
                     padx=0,
                     pady=0)
    word6.grid(row=2, column=0, padx=5, pady=0, sticky="s")

    # 创建第四天天气框架!!!!!
    day19_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][3]), padding=(20, 10))
    day19_frame.grid(row=0, column=4, padx=3, pady=(20, 10), sticky="nsw")
    # 先插一张图片
    tianqi_img19 = tk.Label(day19_frame, image=ifphoto(df['天气'][3]))
    tianqi_img19.grid(row=0, column=0)
    # 再插一个大文本
    word7 = tk.Label(day19_frame,
                     text='\n{}\n'.format(df['天气'][3]),
                     font=('仿宋', 22),
                     padx=0,
                     pady=0)
    word7.grid(row=1, column=0, padx=5, pady=0, sticky="s")
    # 再插几行小文本
    word8 = tk.Label(day19_frame,
                     text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][3], df['最高气温'][3], df['风级'][3],
                                                      df['日期'][3]),
                     font=('微软雅黑', 10),
                     padx=0,
                     pady=0)
    word8.grid(row=2, column=0, padx=5, pady=0, sticky="s")

    # 创建第五天天气框架!!!!!
    day20_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][4]), padding=(20, 10))
    day20_frame.grid(row=0, column=5, padx=2, pady=(20, 10), sticky="nsw")
    # 先插一张图片
    tianqi_img20 = tk.Label(day20_frame, image=ifphoto(df['天气'][4]))
    tianqi_img20.grid(row=0, column=0)
    # 再插一个大文本
    word9 = tk.Label(day20_frame,
                     text='\n{}\n'.format(df['天气'][4]),
                     font=('仿宋', 22),
                     padx=0,
                     pady=0)
    word9.grid(row=1, column=0, padx=5, pady=0, sticky="s")
    # 再插几行小文本
    word10 = tk.Label(day20_frame,
                      text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][4], df['最高气温'][4], df['风级'][4],
                                                       df['日期'][4]),
                      font=('微软雅黑', 10),
                      padx=0,
                      pady=0)
    word10.grid(row=2, column=0, padx=5, pady=0, sticky="s")

    # 创建第六天天气框架!!!!!
    day21_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][5]), padding=(20, 10))
    day21_frame.grid(row=0, column=6, padx=2, pady=(20, 10), sticky="nsw")
    # 先插一张图片
    tianqi_img21 = tk.Label(day21_frame, image=ifphoto(df['天气'][5]))
    tianqi_img21.grid(row=0, column=0)
    # 再插一个大文本
    word11 = tk.Label(day21_frame,
                      text='\n{}\n'.format(df['天气'][5]),
                      font=('仿宋', 22),
                      padx=0,
                      pady=0)
    word11.grid(row=1, column=0, padx=5, pady=0, sticky="s")
    # 再插几行小文本
    word12 = tk.Label(day21_frame,
                      text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][5], df['最高气温'][5], df['风级'][5],
                                                       df['日期'][5]),
                      font=('微软雅黑', 10),
                      padx=0,
                      pady=0)
    word12.grid(row=2, column=0, padx=5, pady=0, sticky="s")

    # 创建第七天天气框架!!!!!
    day22_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][6]), padding=(20, 10))
    day22_frame.grid(row=0, column=7, padx=1, pady=(20, 10), sticky="nsw")
    # 先插一张图片
    tianqi_img22 = tk.Label(day22_frame, image=ifphoto(df['天气'][6]))
    tianqi_img22.grid(row=0, column=0)
    # 再插一个大文本
    word13 = tk.Label(day22_frame,
                      text='\n{}\n'.format(df['天气'][6]),
                      font=('仿宋', 22),
                      padx=0,
                      pady=0)
    word13.grid(row=1, column=0, padx=5, pady=0, sticky="s")
    # 再插几行小文本
    word14 = tk.Label(day22_frame,
                      text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][6], df['最高气温'][6], df['风级'][6],
                                                       df['日期'][6]),
                      font=('微软雅黑', 10),
                      padx=0,
                      pady=0)
    word14.grid(row=2, column=0, padx=5, pady=0, sticky="s")

    print('7天天气情况插入成功')

为了方便调试位置,7个相同的组件我没有用for循环定义,这里有待改进。

15天的代码我只列举前三个:

def tianqilan15():
    global day1_frame, day2_frame, day3_frame, day4_frame, day5_frame, day6_frame, day7_frame, day8_frame
    global day9_frame, day10_frame, day11_frame, day12_frame, day13_frame, day14_frame, day15_frame
    global tianqi15flag

    jiazaitubiao()
    tianqi15flag = 1

    # 创建第1天天气框架!!!!!
    day1_frame = ttk.LabelFrame(frame1, text='今天'.format(df['星期'][0]), padding=(20, 10))
    day1_frame.grid(row=0, column=1, padx=26, pady=20, sticky="n")
    # 插一个大文本
    word1 = tk.Label(day1_frame,
                     text='{}'.format(df['天气'][0]),
                     font=('仿宋', 16),
                     padx=0,
                     pady=0)
    word1.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
    # 再插几行小文本
    word2 = tk.Label(day1_frame,
                     text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][0], df['最高气温'][0], df['风级'][0],
                                                      df['日期'][0]),
                     font=('微软雅黑', 10),
                     padx=0,
                     pady=0)
    word2.grid(row=1, column=0, padx=5, pady=0, sticky="nsew")

    # 创建第2天天气框架!!!!!
    day2_frame = ttk.LabelFrame(frame1, text='明天'.format(df['星期'][1]), padding=(20, 10))
    day2_frame.grid(row=0, column=2, padx=26, pady=20, sticky="n")
    # 插一个大文本
    word3 = tk.Label(day2_frame,
                     text='{}'.format(df['天气'][1]),
                     font=('仿宋', 16),
                     padx=0,
                     pady=0)
    word3.grid(row=0, column=0, padx=0, pady=0, sticky="n")
    # 再插几行小文本
    word4 = tk.Label(day2_frame,
                     text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][1], df['最高气温'][1], df['风级'][1],
                                                      df['日期'][1]),
                     font=('微软雅黑', 10),
                     padx=0,
                     pady=0)
    word4.grid(row=1, column=0, padx=5, pady=0, sticky="n")

    # 创建第3天天气框架!!!!!
    day3_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][2]), padding=(20, 10))
    day3_frame.grid(row=0, column=3, padx=25, pady=20, sticky="n")
    # 插一个大文本
    word5 = tk.Label(day3_frame,
                     text='{}'.format(df['天气'][2]),
                     font=('仿宋', 16),
                     padx=0,
                     pady=0)
    word5.grid(row=0, column=0, padx=0, pady=0, sticky="n")
    # 再插几行小文本
    word6 = tk.Label(day3_frame,
                     text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][2], df['最高气温'][2], df['风级'][2],
                                                      df['日期'][2]),
                     font=('微软雅黑', 10),
                     padx=0,
                     pady=0)
    word6.grid(row=1, column=0, padx=5, pady=0, sticky="n")

    print('15天天气情况插入成功')

4、利用csv文件制作折线图与统计图(饼状图)

利用matplotlib库,写了四个函数,分别用于制作7天的折线图、15天的折线图、7天的统计图、15天的统计图。代码如下:

import matplotlib.pyplot as plt
import pandas as pd

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['axes.unicode_minus'] = False


def line7_get():
    data = pd.read_csv('weather7.csv', encoding='gb18030')

    xdata = data.iloc[:, 0]
    y1data = data.iloc[:, 3]
    y2data = data.iloc[:, 4]
    fig = plt.figure(dpi=96, figsize=(20, 9))
    plt.plot(xdata, y1data, color='b', marker='o', mec='b', mfc='w', label=u'最低气温')
    plt.plot(xdata, y2data, color='r', marker='o', mec='r', mfc='w',
             label=u'最高气温')  # color可自定义折线颜色,marker可自定义点形状,label为折线标注
    # plt.title(u"未来15天气温折线图", size=20)
    plt.legend()
    plt.xlabel(u' ', size=100)
    plt.legend(prop={'size': 22})
    plt.yticks(size=20, weight='bold')
    plt.xticks(size=20, weight='bold')
    plt.ylabel(u'摄氏度', size=30)
    plt.savefig("line7.png")


def line15_get():
    data = pd.read_csv('weather15.csv', encoding='gb18030')

    xdata = data.iloc[:, 0]
    y1data = data.iloc[:, 3]
    y2data = data.iloc[:, 4]
    fig = plt.figure(dpi=96, figsize=(20, 9))
    plt.plot(xdata, y1data, color='b', marker='o', mec='b', mfc='w', label=u'最低气温')
    plt.plot(xdata, y2data, color='r', marker='o', mec='r', mfc='w',
             label=u'最高气温')  # color可自定义折线颜色,marker可自定义点形状,label为折线标注
    # plt.title(u"未来15天气温折线图", size=20)
    plt.legend()
    plt.xlabel(u' ', size=100)
    plt.legend(prop={'size': 22})
    plt.yticks(size=20, weight='bold')
    plt.xticks(size=20, weight='bold')
    plt.ylabel(u'摄氏度', size=30)
    plt.savefig("line15.png")


def tong15_get():
    data = pd.read_csv('weather15.csv', encoding='gb18030')

    xdata = data.iloc[:, 2]
    weather = list(xdata)
    dic_wea = {}
    for i in range(0, 15):
        if weather[i] in dic_wea.keys():
            dic_wea[weather[i]] += 1
        else:
            dic_wea[weather[i]] = 1

    explode = [0.01] * len(dic_wea.keys())
    fig = plt.figure(dpi=128, figsize=(10, 6))
    color = ['lightskyblue', 'silver', 'yellow', 'salmon', 'grey', 'lime', 'gold', 'red', 'green', 'pink']
    patches, l_text, p_text = plt.pie(dic_wea.values(), explode=explode, labels=dic_wea.keys(), autopct='%1.1f%%',
                                      colors=color)
    for t in l_text:
        t.set_size(25)
    for t in p_text:
        t.set_size(25)
    plt.savefig("tong15.png")


def tong7_get():
    data = pd.read_csv('weather7.csv', encoding='gb18030')

    xdata = data.iloc[:, 2]
    weather = list(xdata)
    dic_wea = {}
    for i in range(0, 7):
        if weather[i] in dic_wea.keys():
            dic_wea[weather[i]] += 1
        else:
            dic_wea[weather[i]] = 1

    explode = [0.01] * len(dic_wea.keys())
    fig = plt.figure(dpi=128, figsize=(10, 6))
    color = ['lightskyblue', 'silver', 'yellow', 'salmon', 'grey', 'lime', 'gold', 'red', 'green', 'pink']
    patches, l_text, p_text = plt.pie(dic_wea.values(), explode=explode, labels=dic_wea.keys(), autopct='%1.1f%%',
                                      colors=color)
    for t in l_text:
        t.set_size(25)
    for t in p_text:
        t.set_size(25)
    plt.savefig("tong7.png")

同样的,这一部分代码只是定义了四个函数,用于主py文件的调用,并不能独立运行。

5、按下“折线图”按钮的启动函数(统计图类似)

这里有个判断:当同时输入城市与模式的适合才能按下按钮,否则终端输出“请正确选择!”

# 设置折线按钮:得到折线图与天气栏
def get_line_chart():
    global df

    if var_4.get() != '城市' and var_6.get() != '模式':
        # 爬取到城市var_4未来15天的数据
        weather_spider(var_4.get())
        # 处理一下
        df = pd.read_csv('weather15.csv', encoding='gb18030')
        # 这里放天气图和折线图
        if var_6.get() == '7天':
            forgettianqi()
            tianqilan7()
            # bujuforget()
            buju('折线图', 540, 580)
            chartforget()
            line7fun()  # 7天统计图
        elif var_6.get() == '15天':
            forgettianqi()
            tianqilan15()
            bujuforget()
            buju('折线图', 540, 650)
            chartforget()
            line15fun()  # 15天统计图
    else:
        print('请正确选择!')

6、其他小功能实现

(1)启动画面:添加一张图然后两秒后不显示

def begin():
    global begin

    def close():
        begin_img.place_forget()

    begin_pic = Image.open("main.png")
    begin_pic = begin_pic.resize((1038, 678))
    begin = ImageTk.PhotoImage(begin_pic)
    begin_img = tk.Label(frame1, image=begin)
    begin_img.place(x=0, y=0)
    frame1.after(2000, close)

(2)定义并判断插哪一张图像

# 将天气图标进行命名
def jiazaitubiao():
    global xiaoyu, yin, yu, duoyun, qing
    photo1 = Image.open("weather_xiaoyu.png")
    photo2 = Image.open("weather_yu.png")
    photo3 = Image.open("weather_yin.png")
    photo4 = Image.open("weather_duoyun.png")
    photo5 = Image.open("weather_qing.png")
    photo1 = photo1.resize((60, 60))
    photo2 = photo2.resize((60, 60))
    photo3 = photo3.resize((60, 60))
    photo4 = photo4.resize((60, 60))
    photo5 = photo5.resize((60, 60))
    xiaoyu = ImageTk.PhotoImage(photo1)
    yu = ImageTk.PhotoImage(photo2)
    yin = ImageTk.PhotoImage(photo3)
    duoyun = ImageTk.PhotoImage(photo4)
    qing = ImageTk.PhotoImage(photo5)


# 判断使用哪一副画
def ifphoto(weather):
    if '小雨' in weather:
        ans = xiaoyu
    elif '雨' in weather:
        ans = yu
    elif '阴' in weather:
        ans = yin
    elif '多云' in weather:
        ans = duoyun
    elif '晴' in weather:
        ans = qing
    return ans

(3)标志位的使用

在一张图切换另一张图,一组labelframe换另一组labelframe时,不将旧图移除会重叠显示的。由于我们图片和labelframe定义和放置都是写在一起的,所以当某图片没放出来时就代表它没有被定义,此时要求移除会报错没有定义。这里我们定义了标志位,实现了判断某图片到底有么有放出来。

利用标志位移除天气显示栏的代码:(移除图片相似)

# 关闭天气栏
def forgettianqi():
    global tianqi15flag
    global tianqi7flag

    if tianqi15flag == 1:  # 判断是否有15天的放下
        tianqi15flag = 0
        day1_frame.grid_forget()
        day2_frame.grid_forget()
        day3_frame.grid_forget()
        day4_frame.grid_forget()
        day5_frame.grid_forget()
        day6_frame.grid_forget()
        day7_frame.grid_forget()
        day8_frame.grid_forget()
        day9_frame.grid_forget()
        day10_frame.grid_forget()
        day11_frame.grid_forget()
        day12_frame.grid_forget()
        day13_frame.grid_forget()
        day14_frame.grid_forget()
        day15_frame.grid_forget()
    if tianqi7flag == 1:
        tianqi7flag = 0
        day16_frame.grid_forget()
        day17_frame.grid_forget()
        day18_frame.grid_forget()
        day19_frame.grid_forget()
        day20_frame.grid_forget()
        day21_frame.grid_forget()
        day22_frame.grid_forget()

改进:

由于时间匆忙,程序有很多值得改进的地方:

1、定义了7+15共22个labelframe,其实可以用for循环定义,大大减少工作量
2、爬取生成两个文件实属偷懒,其实只生成15天的,取前7天的就可以相当于有两个文件
3、暗夜模式下图表显示框的白边过于丑陋,想想办法改成输出透明的png图

物联沃分享整理
物联沃-IOTWORD物联网 » 使用Python爬取天气数据并制作天气预报对话框

发表评论