当前位置:   article > 正文

Python:爬取天气并设计制作天气预报对话框_如何用python爬取天气预报

如何用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文件。

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

  1. import requests
  2. from bs4 import BeautifulSoup
  3. import csv
  4. import os
  5. def getHTMLtext(url):
  6. try:
  7. r = requests.get(url, timeout=30)
  8. r.raise_for_status()
  9. r.encoding = r.apparent_encoding
  10. print("成功访问")
  11. return r.text
  12. except:
  13. print("访问错误")
  14. return " "
  15. def get_content(html):
  16. final = [] # 初始化一个列表保存数据
  17. bs = BeautifulSoup(html, "html.parser") # 创建BeautifulSoup对象
  18. body = bs.body
  19. data = body.find('div', {'id': '7d'}) # 找到div标签且id = 7d
  20. # 下面爬取7天的数据
  21. ul = data.find('ul') # 找到所有的ul标签
  22. li = ul.find_all('li') # 找到左右的li标签
  23. i = 0 # 控制爬取的天数
  24. for day in li: # 遍历找到的每一个li
  25. if 7 > i >= 0:
  26. temp = [] # 临时存放每天的数据
  27. date = day.find('h1').string # 得到日期
  28. date1 = date[0:date.index('(')]
  29. temp.append(date1)
  30. week = date[date.index('(')+1:date.index(')')] # 得到星期
  31. temp.append(week)
  32. inf = day.find_all('p') # 找出li下面的p标签,提取第一个p标签的值,即天气
  33. wea = inf[0].string
  34. if '转' in wea:
  35. wea = wea[0:wea.index('转')]
  36. temp.append(wea)
  37. tem_low = inf[1].find('i').string # 找到最低气温
  38. temp.append(tem_low[:-1])
  39. if inf[1].find('span') is None: # 天气预报可能没有最高气温
  40. tem_high = None
  41. temp.append(tem_high)
  42. else:
  43. tem_high = inf[1].find('span').string # 找到最高气温
  44. if tem_high[-1] == '℃':
  45. temp.append(tem_high[:-1])
  46. else:
  47. temp.append(tem_high)
  48. wind_scale = inf[2].find('i').string # 找到风级
  49. wind = wind_scale[0:wind_scale.index('级')]
  50. temp.append(wind)
  51. final.append(temp)
  52. i = i + 1
  53. return final
  54. def get_content2(html):
  55. final = [] # 初始化一个列表保存数据
  56. bs = BeautifulSoup(html, "html.parser") # 创建BeautifulSoup对象
  57. body = bs.body
  58. data = body.find('div', {'id': '15d'}) # 找到div标签且id = 15d
  59. ul = data.find('ul') # 找到所有的ul标签
  60. li = ul.find_all('li') # 找到左右的li标签
  61. i = 0 # 控制爬取的天数
  62. for day in li: # 遍历找到的每一个li
  63. if i < 8:
  64. temp = [] # 临时存放每天的数据
  65. date = day.find('span', {'class': 'time'}).string # 得到日期
  66. date1 = date[date.index('(') + 1:-1] # 取出日期号
  67. temp.append(date1)
  68. week = date[0:date.index('(')]
  69. temp.append(week)
  70. weather = day.find('span', {'class': 'wea'}).string # 找到天气
  71. if '转' in weather:
  72. weather = weather[0:weather.index('转')]
  73. temp.append(weather)
  74. tem = day.find('span', {'class': 'tem'}).text # 找到温度
  75. temp.append(tem[tem.index('/') + 1:-1]) # 找到最低气温
  76. temp.append(tem[:tem.index('/') - 1]) # 找到最高气温
  77. wind_scale = day.find('span', {'class': 'wind1'}).string # 找到风级
  78. wind = wind_scale[0:wind_scale.index('级')]
  79. temp.append(wind)
  80. final.append(temp)
  81. return final
  82. def write_to_csv(file_name, data):
  83. with open(file_name, 'a', errors='ignore', newline='') as f:
  84. header = ['日期', '星期', '天气', '最低气温', '最高气温', '风级']
  85. f_csv = csv.writer(f)
  86. f_csv.writerow(header)
  87. f_csv.writerows(data)
  88. def main(city):
  89. if city == '西安':
  90. erea = '101110101'
  91. if city == '武汉':
  92. erea = '101200101'
  93. if city == '深圳':
  94. erea = '101280601'
  95. if city == '上海':
  96. erea = '101020100'
  97. if city == '哈尔滨':
  98. erea = '101050101'
  99. url1 = 'http://www.weather.com.cn/weather/' + erea + '.shtml' # 7天天气中国天气网
  100. url2 = 'http://www.weather.com.cn/weather15d/' + erea + '.shtml' # 8-15天天气中国天气网
  101. html1 = getHTMLtext(url1)
  102. data1_7 = get_content(html1) # 获得1-7天和当天的数据
  103. html2 = getHTMLtext(url2)
  104. data8_15 = get_content2(html2) # 获得8-15天数据
  105. data15 = data1_7 + data8_15
  106. if os.path.isfile("weather15.csv"): # 检查文件是否存在
  107. os.remove("weather15.csv") # 删除文件
  108. if os.path.isfile("weather7.csv"): # 检查文件是否存在
  109. os.remove("weather7.csv") # 删除文件
  110. write_to_csv('weather7.csv', data1_7) # 保存为csv文件
  111. write_to_csv('weather15.csv', data15) # 保存为csv文件

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

2、建立选项对话框

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

  1. # 选项栏显示
  2. def xuanxianglan():
  3. global var_4, var_6
  4. option_city_list = ["城市", "西安", "武汉", "深圳", "上海", "哈尔滨"]
  5. option_mode_list = ["模式", "7天", "15天"]
  6. var_4 = tk.StringVar(value=option_city_list[1]) # 存储城市
  7. var_6 = tk.StringVar(value=option_mode_list[1])
  8. # 创建一个框架!!!!!!!
  9. check_frame = ttk.LabelFrame(frame1, text="选项", padding=(20, 10))
  10. check_frame.grid(row=0, column=0, padx=(20, 10), pady=(20, 10), sticky="nw")
  11. # 创建选择列表选择城市
  12. optionmenucity = ttk.OptionMenu(check_frame, var_4, *option_city_list)
  13. optionmenucity.grid(row=0, column=0, padx=5, pady=10, sticky="nsew")
  14. # 创建选择列表选择模式
  15. optionmenumode = ttk.OptionMenu(check_frame, var_6, *option_mode_list)
  16. optionmenumode.grid(row=1, column=0, padx=5, pady=10, sticky="nsew")
  17. # 创建按钮切换统计图
  18. button = ttk.Button(check_frame, text="统计图")
  19. button.grid(row=2, column=0, padx=5, pady=10, sticky="nsew")
  20. button.config(command=get_statistic)
  21. # 创建按钮切换折线图
  22. button1 = ttk.Button(check_frame, text="折线图")
  23. button1.grid(row=3, column=0, padx=5, pady=10, sticky="nsew")
  24. button1.config(command=get_line_chart)
  25. var_1 = tk.StringVar()
  26. def callCheckbutton():
  27. if var_1.get() == '1':
  28. root.tk.call("set_theme", "dark")
  29. else:
  30. root.tk.call("set_theme", "light")
  31. # Switch来切换暗夜模式
  32. switchdark = ttk.Checkbutton(check_frame, variable=var_1, text="Dark", style="Switch.TCheckbutton",
  33. command=callCheckbutton)
  34. 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排列。

七天的代码如下:

  1. # 7天的天气栏显示
  2. def tianqilan7():
  3. global day16_frame, day17_frame, day18_frame, day19_frame, day20_frame, day21_frame, day22_frame
  4. global tianqi7flag
  5. jiazaitubiao()
  6. tianqi7flag = 1
  7. # 创建第一天天气框架!!!!!
  8. day16_frame = ttk.LabelFrame(frame1, text='今天'.format(df['星期'][0]), padding=(20, 10))
  9. day16_frame.grid(row=0, column=1, padx=0, pady=(20, 10), sticky="nsw")
  10. # 先插一张图片
  11. tianqi_img16 = tk.Label(day16_frame, image=ifphoto(df['天气'][0]))
  12. tianqi_img16.grid(row=0, column=0)
  13. # 再插一个大文本
  14. word1 = tk.Label(day16_frame,
  15. text='\n{}\n'.format(df['天气'][0]),
  16. font=('仿宋', 22),
  17. padx=0,
  18. pady=0)
  19. word1.grid(row=1, column=0, padx=5, pady=0, sticky="s")
  20. # 再插几行小文本
  21. word2 = tk.Label(day16_frame,
  22. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][0], df['最高气温'][0], df['风级'][0],
  23. df['日期'][0]),
  24. font=('微软雅黑', 10),
  25. padx=0,
  26. pady=0)
  27. word2.grid(row=2, column=0, padx=5, pady=0, sticky="s")
  28. # 创建第二天天气框架!!!!!
  29. day17_frame = ttk.LabelFrame(frame1, text='明天'.format(df['星期'][1]), padding=(20, 10))
  30. day17_frame.grid(row=0, column=2, padx=3, pady=(20, 10), sticky="ns")
  31. # 先插一张图片
  32. tianqi_img17 = tk.Label(day17_frame, image=ifphoto(df['天气'][1]))
  33. tianqi_img17.grid(row=0, column=0)
  34. # 再插一个大文本
  35. word3 = tk.Label(day17_frame,
  36. text='\n{}\n'.format(df['天气'][1]),
  37. font=('仿宋', 22),
  38. padx=0,
  39. pady=0)
  40. word3.grid(row=1, column=0, padx=5, pady=0, sticky="s")
  41. # 再插几行小文本
  42. word4 = tk.Label(day17_frame,
  43. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][1], df['最高气温'][1], df['风级'][1],
  44. df['日期'][1]),
  45. font=('微软雅黑', 10),
  46. padx=0,
  47. pady=0)
  48. word4.grid(row=2, column=0, padx=5, pady=0, sticky="s")
  49. # 创建第三天天气框架!!!!!
  50. day18_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][2]), padding=(20, 10))
  51. day18_frame.grid(row=0, column=3, padx=0, pady=(20, 10), sticky="nsw")
  52. # 先插一张图片
  53. tianqi_img18 = tk.Label(day18_frame, image=ifphoto(df['天气'][2]))
  54. tianqi_img18.grid(row=0, column=0)
  55. # 再插一个大文本
  56. word5 = tk.Label(day18_frame,
  57. text='\n{}\n'.format(df['天气'][2]),
  58. font=('仿宋', 22),
  59. padx=0,
  60. pady=0)
  61. word5.grid(row=1, column=0, padx=5, pady=0, sticky="s")
  62. # 再插几行小文本
  63. word6 = tk.Label(day18_frame,
  64. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][2], df['最高气温'][2], df['风级'][2],
  65. df['日期'][2]),
  66. font=('微软雅黑', 10),
  67. padx=0,
  68. pady=0)
  69. word6.grid(row=2, column=0, padx=5, pady=0, sticky="s")
  70. # 创建第四天天气框架!!!!!
  71. day19_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][3]), padding=(20, 10))
  72. day19_frame.grid(row=0, column=4, padx=3, pady=(20, 10), sticky="nsw")
  73. # 先插一张图片
  74. tianqi_img19 = tk.Label(day19_frame, image=ifphoto(df['天气'][3]))
  75. tianqi_img19.grid(row=0, column=0)
  76. # 再插一个大文本
  77. word7 = tk.Label(day19_frame,
  78. text='\n{}\n'.format(df['天气'][3]),
  79. font=('仿宋', 22),
  80. padx=0,
  81. pady=0)
  82. word7.grid(row=1, column=0, padx=5, pady=0, sticky="s")
  83. # 再插几行小文本
  84. word8 = tk.Label(day19_frame,
  85. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][3], df['最高气温'][3], df['风级'][3],
  86. df['日期'][3]),
  87. font=('微软雅黑', 10),
  88. padx=0,
  89. pady=0)
  90. word8.grid(row=2, column=0, padx=5, pady=0, sticky="s")
  91. # 创建第五天天气框架!!!!!
  92. day20_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][4]), padding=(20, 10))
  93. day20_frame.grid(row=0, column=5, padx=2, pady=(20, 10), sticky="nsw")
  94. # 先插一张图片
  95. tianqi_img20 = tk.Label(day20_frame, image=ifphoto(df['天气'][4]))
  96. tianqi_img20.grid(row=0, column=0)
  97. # 再插一个大文本
  98. word9 = tk.Label(day20_frame,
  99. text='\n{}\n'.format(df['天气'][4]),
  100. font=('仿宋', 22),
  101. padx=0,
  102. pady=0)
  103. word9.grid(row=1, column=0, padx=5, pady=0, sticky="s")
  104. # 再插几行小文本
  105. word10 = tk.Label(day20_frame,
  106. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][4], df['最高气温'][4], df['风级'][4],
  107. df['日期'][4]),
  108. font=('微软雅黑', 10),
  109. padx=0,
  110. pady=0)
  111. word10.grid(row=2, column=0, padx=5, pady=0, sticky="s")
  112. # 创建第六天天气框架!!!!!
  113. day21_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][5]), padding=(20, 10))
  114. day21_frame.grid(row=0, column=6, padx=2, pady=(20, 10), sticky="nsw")
  115. # 先插一张图片
  116. tianqi_img21 = tk.Label(day21_frame, image=ifphoto(df['天气'][5]))
  117. tianqi_img21.grid(row=0, column=0)
  118. # 再插一个大文本
  119. word11 = tk.Label(day21_frame,
  120. text='\n{}\n'.format(df['天气'][5]),
  121. font=('仿宋', 22),
  122. padx=0,
  123. pady=0)
  124. word11.grid(row=1, column=0, padx=5, pady=0, sticky="s")
  125. # 再插几行小文本
  126. word12 = tk.Label(day21_frame,
  127. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][5], df['最高气温'][5], df['风级'][5],
  128. df['日期'][5]),
  129. font=('微软雅黑', 10),
  130. padx=0,
  131. pady=0)
  132. word12.grid(row=2, column=0, padx=5, pady=0, sticky="s")
  133. # 创建第七天天气框架!!!!!
  134. day22_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][6]), padding=(20, 10))
  135. day22_frame.grid(row=0, column=7, padx=1, pady=(20, 10), sticky="nsw")
  136. # 先插一张图片
  137. tianqi_img22 = tk.Label(day22_frame, image=ifphoto(df['天气'][6]))
  138. tianqi_img22.grid(row=0, column=0)
  139. # 再插一个大文本
  140. word13 = tk.Label(day22_frame,
  141. text='\n{}\n'.format(df['天气'][6]),
  142. font=('仿宋', 22),
  143. padx=0,
  144. pady=0)
  145. word13.grid(row=1, column=0, padx=5, pady=0, sticky="s")
  146. # 再插几行小文本
  147. word14 = tk.Label(day22_frame,
  148. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][6], df['最高气温'][6], df['风级'][6],
  149. df['日期'][6]),
  150. font=('微软雅黑', 10),
  151. padx=0,
  152. pady=0)
  153. word14.grid(row=2, column=0, padx=5, pady=0, sticky="s")
  154. print('7天天气情况插入成功')

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

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

  1. def tianqilan15():
  2. global day1_frame, day2_frame, day3_frame, day4_frame, day5_frame, day6_frame, day7_frame, day8_frame
  3. global day9_frame, day10_frame, day11_frame, day12_frame, day13_frame, day14_frame, day15_frame
  4. global tianqi15flag
  5. jiazaitubiao()
  6. tianqi15flag = 1
  7. # 创建第1天天气框架!!!!!
  8. day1_frame = ttk.LabelFrame(frame1, text='今天'.format(df['星期'][0]), padding=(20, 10))
  9. day1_frame.grid(row=0, column=1, padx=26, pady=20, sticky="n")
  10. # 插一个大文本
  11. word1 = tk.Label(day1_frame,
  12. text='{}'.format(df['天气'][0]),
  13. font=('仿宋', 16),
  14. padx=0,
  15. pady=0)
  16. word1.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
  17. # 再插几行小文本
  18. word2 = tk.Label(day1_frame,
  19. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][0], df['最高气温'][0], df['风级'][0],
  20. df['日期'][0]),
  21. font=('微软雅黑', 10),
  22. padx=0,
  23. pady=0)
  24. word2.grid(row=1, column=0, padx=5, pady=0, sticky="nsew")
  25. # 创建第2天天气框架!!!!!
  26. day2_frame = ttk.LabelFrame(frame1, text='明天'.format(df['星期'][1]), padding=(20, 10))
  27. day2_frame.grid(row=0, column=2, padx=26, pady=20, sticky="n")
  28. # 插一个大文本
  29. word3 = tk.Label(day2_frame,
  30. text='{}'.format(df['天气'][1]),
  31. font=('仿宋', 16),
  32. padx=0,
  33. pady=0)
  34. word3.grid(row=0, column=0, padx=0, pady=0, sticky="n")
  35. # 再插几行小文本
  36. word4 = tk.Label(day2_frame,
  37. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][1], df['最高气温'][1], df['风级'][1],
  38. df['日期'][1]),
  39. font=('微软雅黑', 10),
  40. padx=0,
  41. pady=0)
  42. word4.grid(row=1, column=0, padx=5, pady=0, sticky="n")
  43. # 创建第3天天气框架!!!!!
  44. day3_frame = ttk.LabelFrame(frame1, text='{}'.format(df['星期'][2]), padding=(20, 10))
  45. day3_frame.grid(row=0, column=3, padx=25, pady=20, sticky="n")
  46. # 插一个大文本
  47. word5 = tk.Label(day3_frame,
  48. text='{}'.format(df['天气'][2]),
  49. font=('仿宋', 16),
  50. padx=0,
  51. pady=0)
  52. word5.grid(row=0, column=0, padx=0, pady=0, sticky="n")
  53. # 再插几行小文本
  54. word6 = tk.Label(day3_frame,
  55. text='{}~{}℃\n{}级风\n{}'.format(df['最低气温'][2], df['最高气温'][2], df['风级'][2],
  56. df['日期'][2]),
  57. font=('微软雅黑', 10),
  58. padx=0,
  59. pady=0)
  60. word6.grid(row=1, column=0, padx=5, pady=0, sticky="n")
  61. print('15天天气情况插入成功')

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

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

  1. import matplotlib.pyplot as plt
  2. import pandas as pd
  3. plt.rcParams['font.sans-serif'] = ['SimHei']
  4. plt.rcParams['font.family'] = 'sans-serif'
  5. plt.rcParams['axes.unicode_minus'] = False
  6. def line7_get():
  7. data = pd.read_csv('weather7.csv', encoding='gb18030')
  8. xdata = data.iloc[:, 0]
  9. y1data = data.iloc[:, 3]
  10. y2data = data.iloc[:, 4]
  11. fig = plt.figure(dpi=96, figsize=(20, 9))
  12. plt.plot(xdata, y1data, color='b', marker='o', mec='b', mfc='w', label=u'最低气温')
  13. plt.plot(xdata, y2data, color='r', marker='o', mec='r', mfc='w',
  14. label=u'最高气温') # color可自定义折线颜色,marker可自定义点形状,label为折线标注
  15. # plt.title(u"未来15天气温折线图", size=20)
  16. plt.legend()
  17. plt.xlabel(u' ', size=100)
  18. plt.legend(prop={'size': 22})
  19. plt.yticks(size=20, weight='bold')
  20. plt.xticks(size=20, weight='bold')
  21. plt.ylabel(u'摄氏度', size=30)
  22. plt.savefig("line7.png")
  23. def line15_get():
  24. data = pd.read_csv('weather15.csv', encoding='gb18030')
  25. xdata = data.iloc[:, 0]
  26. y1data = data.iloc[:, 3]
  27. y2data = data.iloc[:, 4]
  28. fig = plt.figure(dpi=96, figsize=(20, 9))
  29. plt.plot(xdata, y1data, color='b', marker='o', mec='b', mfc='w', label=u'最低气温')
  30. plt.plot(xdata, y2data, color='r', marker='o', mec='r', mfc='w',
  31. label=u'最高气温') # color可自定义折线颜色,marker可自定义点形状,label为折线标注
  32. # plt.title(u"未来15天气温折线图", size=20)
  33. plt.legend()
  34. plt.xlabel(u' ', size=100)
  35. plt.legend(prop={'size': 22})
  36. plt.yticks(size=20, weight='bold')
  37. plt.xticks(size=20, weight='bold')
  38. plt.ylabel(u'摄氏度', size=30)
  39. plt.savefig("line15.png")
  40. def tong15_get():
  41. data = pd.read_csv('weather15.csv', encoding='gb18030')
  42. xdata = data.iloc[:, 2]
  43. weather = list(xdata)
  44. dic_wea = {}
  45. for i in range(0, 15):
  46. if weather[i] in dic_wea.keys():
  47. dic_wea[weather[i]] += 1
  48. else:
  49. dic_wea[weather[i]] = 1
  50. explode = [0.01] * len(dic_wea.keys())
  51. fig = plt.figure(dpi=128, figsize=(10, 6))
  52. color = ['lightskyblue', 'silver', 'yellow', 'salmon', 'grey', 'lime', 'gold', 'red', 'green', 'pink']
  53. patches, l_text, p_text = plt.pie(dic_wea.values(), explode=explode, labels=dic_wea.keys(), autopct='%1.1f%%',
  54. colors=color)
  55. for t in l_text:
  56. t.set_size(25)
  57. for t in p_text:
  58. t.set_size(25)
  59. plt.savefig("tong15.png")
  60. def tong7_get():
  61. data = pd.read_csv('weather7.csv', encoding='gb18030')
  62. xdata = data.iloc[:, 2]
  63. weather = list(xdata)
  64. dic_wea = {}
  65. for i in range(0, 7):
  66. if weather[i] in dic_wea.keys():
  67. dic_wea[weather[i]] += 1
  68. else:
  69. dic_wea[weather[i]] = 1
  70. explode = [0.01] * len(dic_wea.keys())
  71. fig = plt.figure(dpi=128, figsize=(10, 6))
  72. color = ['lightskyblue', 'silver', 'yellow', 'salmon', 'grey', 'lime', 'gold', 'red', 'green', 'pink']
  73. patches, l_text, p_text = plt.pie(dic_wea.values(), explode=explode, labels=dic_wea.keys(), autopct='%1.1f%%',
  74. colors=color)
  75. for t in l_text:
  76. t.set_size(25)
  77. for t in p_text:
  78. t.set_size(25)
  79. plt.savefig("tong7.png")

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

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

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

  1. # 设置折线按钮:得到折线图与天气栏
  2. def get_line_chart():
  3. global df
  4. if var_4.get() != '城市' and var_6.get() != '模式':
  5. # 爬取到城市var_4未来15天的数据
  6. weather_spider(var_4.get())
  7. # 处理一下
  8. df = pd.read_csv('weather15.csv', encoding='gb18030')
  9. # 这里放天气图和折线图
  10. if var_6.get() == '7天':
  11. forgettianqi()
  12. tianqilan7()
  13. # bujuforget()
  14. buju('折线图', 540, 580)
  15. chartforget()
  16. line7fun() # 7天统计图
  17. elif var_6.get() == '15天':
  18. forgettianqi()
  19. tianqilan15()
  20. bujuforget()
  21. buju('折线图', 540, 650)
  22. chartforget()
  23. line15fun() # 15天统计图
  24. else:
  25. print('请正确选择!')

6、其他小功能实现

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

  1. def begin():
  2. global begin
  3. def close():
  4. begin_img.place_forget()
  5. begin_pic = Image.open("main.png")
  6. begin_pic = begin_pic.resize((1038, 678))
  7. begin = ImageTk.PhotoImage(begin_pic)
  8. begin_img = tk.Label(frame1, image=begin)
  9. begin_img.place(x=0, y=0)
  10. frame1.after(2000, close)

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

  1. # 将天气图标进行命名
  2. def jiazaitubiao():
  3. global xiaoyu, yin, yu, duoyun, qing
  4. photo1 = Image.open("weather_xiaoyu.png")
  5. photo2 = Image.open("weather_yu.png")
  6. photo3 = Image.open("weather_yin.png")
  7. photo4 = Image.open("weather_duoyun.png")
  8. photo5 = Image.open("weather_qing.png")
  9. photo1 = photo1.resize((60, 60))
  10. photo2 = photo2.resize((60, 60))
  11. photo3 = photo3.resize((60, 60))
  12. photo4 = photo4.resize((60, 60))
  13. photo5 = photo5.resize((60, 60))
  14. xiaoyu = ImageTk.PhotoImage(photo1)
  15. yu = ImageTk.PhotoImage(photo2)
  16. yin = ImageTk.PhotoImage(photo3)
  17. duoyun = ImageTk.PhotoImage(photo4)
  18. qing = ImageTk.PhotoImage(photo5)
  19. # 判断使用哪一副画
  20. def ifphoto(weather):
  21. if '小雨' in weather:
  22. ans = xiaoyu
  23. elif '雨' in weather:
  24. ans = yu
  25. elif '阴' in weather:
  26. ans = yin
  27. elif '多云' in weather:
  28. ans = duoyun
  29. elif '晴' in weather:
  30. ans = qing
  31. return ans

(3)标志位的使用

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

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

  1. # 关闭天气栏
  2. def forgettianqi():
  3. global tianqi15flag
  4. global tianqi7flag
  5. if tianqi15flag == 1: # 判断是否有15天的放下
  6. tianqi15flag = 0
  7. day1_frame.grid_forget()
  8. day2_frame.grid_forget()
  9. day3_frame.grid_forget()
  10. day4_frame.grid_forget()
  11. day5_frame.grid_forget()
  12. day6_frame.grid_forget()
  13. day7_frame.grid_forget()
  14. day8_frame.grid_forget()
  15. day9_frame.grid_forget()
  16. day10_frame.grid_forget()
  17. day11_frame.grid_forget()
  18. day12_frame.grid_forget()
  19. day13_frame.grid_forget()
  20. day14_frame.grid_forget()
  21. day15_frame.grid_forget()
  22. if tianqi7flag == 1:
  23. tianqi7flag = 0
  24. day16_frame.grid_forget()
  25. day17_frame.grid_forget()
  26. day18_frame.grid_forget()
  27. day19_frame.grid_forget()
  28. day20_frame.grid_forget()
  29. day21_frame.grid_forget()
  30. day22_frame.grid_forget()

改进:

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/362817
推荐阅读
相关标签
  

闽ICP备14008679号