You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
4.0 KiB
114 lines
4.0 KiB
import requests
|
|
from lxml import etree
|
|
import csv
|
|
from collections import Counter
|
|
import pandas as pd
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
def getweather(url):
|
|
weather_info = []
|
|
high_temps = [] # 存储最高气温
|
|
low_temps = [] # 存储最低气温
|
|
weather_conditions = []
|
|
headers = {
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0'
|
|
}
|
|
|
|
response = requests.get(url, headers=headers)
|
|
html_resp = etree.HTML(response.text)
|
|
resp_list = html_resp.xpath("//ul[@class='thrui']/li")
|
|
for li in resp_list:
|
|
day_weather_info = {}
|
|
day_weather_info['date_time'] = li.xpath('./div[1]/text()')[0].split(' ')[0]
|
|
high = li.xpath('./div[2]/text()')[0]
|
|
high_temp = float(high[:high.find('C')])
|
|
day_weather_info['high'] = high_temp
|
|
high_temps.append(high_temp)
|
|
low = li.xpath('./div[3]/text()')[0]
|
|
low_temp = float(low[:low.find('C')])
|
|
day_weather_info['low'] = low_temp
|
|
low_temps.append(low_temp)
|
|
day_weather = li.xpath('./div[4]/text()')[0]
|
|
day_weather_info['weather'] = day_weather
|
|
weather_conditions.append(day_weather)
|
|
weather_info.append(day_weather_info)
|
|
|
|
return weather_info, high_temps, low_temps, weather_conditions
|
|
|
|
|
|
weathers = []
|
|
high_temps = []
|
|
low_temps = []
|
|
weather_conditions = []
|
|
|
|
for month in range(1, 13):
|
|
weather_time = '2022' + ('0' + str(month) if month < 10 else str(month))
|
|
url = f'https://lishi.tianqi.com/guilin/{weather_time}.html'
|
|
weather, highs, lows, conditions = getweather(url)
|
|
weathers.append(weather)
|
|
high_temps.extend(highs)
|
|
low_temps.extend(lows)
|
|
weather_conditions.extend(conditions)
|
|
|
|
with open('weather.csv', 'w', newline='') as csvfile:
|
|
writer = csv.writer(csvfile)
|
|
writer.writerow(['日期', '最高气温', '最低气温', '天气'])
|
|
writer.writerows(
|
|
[list(day_weather_dict.values()) for month_weather in weathers for day_weather_dict in month_weather])
|
|
|
|
weather_counts = Counter(weather_conditions)
|
|
|
|
writer.writerow([])
|
|
writer.writerow(['天气状况', '出现次数'])
|
|
writer.writerows(weather_counts.items())
|
|
|
|
|
|
def plot_weather_counts(weather_counts):
|
|
df = pd.DataFrame(list(weather_counts.items()), columns=['天气状况', '出现次数'])
|
|
|
|
plt.rcParams['font.sans-serif'] = ['SimHei']
|
|
|
|
bar_width = 0.5 # 设置柱子的宽度
|
|
bar_spacing = 0.3 # 设置柱子之间的间隔
|
|
|
|
x_positions = range(len(df['天气状况'])) # 设置x轴位置
|
|
plt.bar(x_positions, df['出现次数'], width=bar_width)
|
|
plt.xlabel('天气状况')
|
|
plt.ylabel('出现次数')
|
|
plt.title('天气状况统计')
|
|
plt.xticks(x_positions, df['天气状况'], rotation=45, ha='right') # 设置x轴标签
|
|
|
|
|
|
def plot_average_temperatures(high_temps, low_temps):
|
|
avg_high_temps = [sum(high_temps[i:i + 30]) / len(high_temps[i:i + 30]) for i in range(0, len(high_temps), 30)]
|
|
avg_low_temps = [sum(low_temps[i:i + 30]) / len(low_temps[i:i + 30]) for i in range(0, len(low_temps), 30)]
|
|
|
|
plt.rcParams['font.sans-serif'] = ['SimHei']
|
|
|
|
months = range(1, 13)
|
|
plt.plot(months[:len(avg_high_temps)], avg_high_temps, marker='o', label='平均最高气温')
|
|
plt.plot(months[:len(avg_low_temps)], avg_low_temps, marker='o', label='平均最低气温')
|
|
|
|
plt.xlabel('月份')
|
|
plt.ylabel('平均气温')
|
|
plt.title('每月平均气温')
|
|
plt.xticks(months)
|
|
plt.legend()
|
|
|
|
|
|
# 创建第一个图表,并绘制天气情况柱状图
|
|
fig1, ax1 = plt.subplots()
|
|
plot_weather_counts(weather_counts)
|
|
ax1.set_ylabel('出现次数')
|
|
ax1.set_title('天气状况统计')
|
|
|
|
# 创建第二个图表,并绘制平均气温折线图
|
|
fig2, ax2 = plt.subplots()
|
|
plot_average_temperatures(high_temps, low_temps)
|
|
ax2.set_xlabel('月份')
|
|
ax2.set_ylabel('平均气温')
|
|
ax2.set_title('每月平均气温')
|
|
|
|
plt.show()
|