包含编程籽料、学习路线图、爬虫代码、安装包等!【点击领取】
本文将介绍如何使用Python爬取天气数据,并进行可视化分析。我们将使用中国天气网作为数据源,通过requests和BeautifulSoup进行数据爬取,然后使用pandas进行数据处理,最后使用matplotlib和pyecharts进行可视化展示。
一、爬取天气数据
- 准备工作
首先安装必要的库:
pip install requests beautifulsoup4 pandas matplotlib pyecharts
- 爬虫代码实现
import requests
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime
import re
import time
import random
class WeatherSpider:
def __init__(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
self.base_url = "http://www.weather.com.cn/weather/"
def get_city_code(self, city_name):
"""获取城市代码"""
city_codes = {
'北京': '101010100',
'上海': '101020100',
'广州': '101280101',
'深圳': '101280601',
'杭州': '101210101',
'成都': '101270101',
'武汉': '101200101',
'南京': '101190101',
'重庆': '101040100',
'西安': '101110101'
}
return city_codes.get(city_name, '101010100') # 默认返回北京
def parse_weather_data(self, html_text):
"""解析天气数据"""
soup = BeautifulSoup(html_text, 'html.parser')
weather_list = []
# 获取7天天气预报
days = soup.find('ul', class_='t clearfix').find_all('li')
for day in days:
try:
date = day.find('h1').text
weather = day.find('p', class_='wea').text
temp = day.find('p', class_='tem')
high_temp = temp.find('span').text.replace('℃', '')
low_temp = temp.find('i').text.replace('℃', '')
wind = day.find('p', class_='win').find('i').text
weather_data = {
'日期': date,
'天气': weather,
'最高温度': int(high_temp),
'最低温度': int(low_temp),
'风力': wind
}
weather_list.append(weather_data)
except Exception as e:
print(f"解析天气数据出错: {e}")
continue
return weather_list
def crawl_weather(self, city_name, days=7):
"""爬取指定城市的天气数据"""
city_code = self.get_city_code(city_name)
url = f"{self.base_url}{city_code}.shtml"
try:
response = requests.get(url, headers=self.headers)
response.raise_for_status()
response.encoding = 'utf-8'
weather_data = self.parse_weather_data(response.text)
df = pd.DataFrame(weather_data)
df['城市'] = city_name
# 添加爬取时间
df['爬取时间'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"成功爬取{city_name}的天气数据")
return df
except Exception as e:
print(f"爬取{city_name}天气数据失败: {e}")
return pd.DataFrame()
def crawl_multiple_cities(self, city_names, save_path='weather_data.csv'):
"""爬取多个城市的天气数据"""
all_data = []
for city in city_names:
df = self.crawl_weather(city)
if not df.empty:
all_data.append(df)
time.sleep(random.uniform(1, 3)) # 随机延迟
if all_data:
result = pd.concat(all_data, ignore_index=True)
result.to_csv(save_path, index=False, encoding='utf-8-sig')
print(f"天气数据已保存到 {save_path}")
return result
else:
print("没有获取到任何天气数据")
return pd.DataFrame()
if __name__ == "__main__":
spider = WeatherSpider()
cities = ['北京', '上海', '广州', '深圳', '杭州', '成都']
weather_df = spider.crawl_multiple_cities(cities)
二、数据可视化分析
- 使用Matplotlib进行基础可视化
import matplotlib.pyplot as plt
import seaborn as sns
def matplotlib_visualization(df):
"""使用Matplotlib进行可视化"""
plt.figure(figsize=(15, 10))
# 1. 各城市最高温度对比
plt.subplot(2, 2, 1)
sns.barplot(x='城市', y='最高温度', data=df, ci=None)
plt.title('各城市最高温度对比')
plt.xticks(rotation=45)
# 2. 各城市最低温度对比
plt.subplot(2, 2, 2)
sns.barplot(x='城市', y='最低温度', data=df, ci=None)
plt.title('各城市最低温度对比')
plt.xticks(rotation=45)
# 3. 温度变化折线图
plt.subplot(2, 2, 3)
for city in df['城市'].unique():
city_data = df[df['城市'] == city]
plt.plot(city_data['日期'], city_data['最高温度'], label=f'{city}最高温', marker='o')
plt.plot(city_data['日期'], city_data['最低温度'], label=f'{city}最低温', linestyle='--', marker='x')
plt.title('未来7天温度变化趋势')
plt.xticks(rotation=45)
plt.legend()
# 4. 天气状况分布
plt.subplot(2, 2, 4)
weather_counts = df['天气'].value_counts()
plt.pie(weather_counts, labels=weather_counts.index, autopct='%1.1f%%')
plt.title('天气状况分布')
plt.tight_layout()
plt.savefig('weather_analysis_matplotlib.png', dpi=300)
plt.show()
# 使用示例
if 'weather_df' in locals() and not weather_df.empty:
matplotlib_visualization(weather_df)
- 使用Pyecharts进行交互式可视化
from pyecharts import options as opts
from pyecharts.charts import Bar, Line, Pie, Grid, Tab
from pyecharts.globals import ThemeType
def pyecharts_visualization(df):
"""使用Pyecharts进行交互式可视化"""
tab = Tab()
# 1. 温度对比柱状图
cities = df['城市'].unique()
high_temp = [df[df['城市'] == city]['最高温度'].mean() for city in cities]
low_temp = [df[df['城市'] == city]['最低温度'].mean() for city in cities]
bar = (
Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
.add_xaxis(cities.tolist())
.add_yaxis("平均最高温度", high_temp)
.add_yaxis("平均最低温度", low_temp)
.set_global_opts(
title_opts=opts.TitleOpts(title="各城市平均温度对比"),
toolbox_opts=opts.ToolboxOpts(),
datazoom_opts=opts.DataZoomOpts(),
)
)
tab.add(bar, "温度对比")
# 2. 温度变化趋势图
line = Line()
for city in cities:
city_data = df[df['城市'] == city]
line.add_xaxis(city_data['日期'].tolist())
line.add_yaxis(
f"{city}-最高温",
city_data['最高温度'].tolist(),
is_smooth=True,
symbol="circle",
symbol_size=8,
label_opts=opts.LabelOpts(is_show=False),
)
line.add_yaxis(
f"{city}-最低温",
city_data['最低温度'].tolist(),
is_smooth=True,
symbol="rect",
symbol_size=8,
linestyle_opts=opts.LineStyleOpts(type_="dashed"),
label_opts=opts.LabelOpts(is_show=False),
)
line.set_global_opts(
title_opts=opts.TitleOpts(title="未来7天温度变化趋势"),
toolbox_opts=opts.ToolboxOpts(),
datazoom_opts=opts.DataZoomOpts(),
tooltip_opts=opts.TooltipOpts(trigger="axis"),
)
tab.add(line, "温度趋势")
# 3. 天气状况饼图
weather_counts = df['天气'].value_counts()
pie = (
Pie()
.add(
"",
[list(z) for z in zip(weather_counts.index, weather_counts)],
radius=["40%", "75%"],
)
.set_global_opts(
title_opts=opts.TitleOpts(title="天气状况分布"),
toolbox_opts=opts.ToolboxOpts(),
legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)"))
)
tab.add(pie, "天气分布")
# 4. 组合图表 - 城市天气日历
weather_data = []
for city in cities:
city_data = df[df['城市'] == city]
for _, row in city_data.iterrows():
weather_data.append([city, row['日期'], row['最高温度'], row['最低温度'], row['天气']])
heatmap = (
HeatMap()
.add_xaxis(cities.tolist())
.add_yaxis(
"天气日历",
[d[1] for d in weather_data],
[[d[0], d[1], d[2]] for d in weather_data],
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="城市天气日历"),
visualmap_opts=opts.VisualMapOpts(
min_=df['最低温度'].min(),
max_=df['最高温度'].max(),
is_piecewise=True,
pos_top="center",
),
toolbox_opts=opts.ToolboxOpts(),
)
)
tab.add(heatmap, "天气日历")
tab.render("weather_analysis_pyecharts.html")
return tab
# 使用示例
if 'weather_df' in locals() and not weather_df.empty:
pyecharts_visualization(weather_df)
三、完整分析报告生成
def generate_weather_report(df, output_file='weather_report.html'):
"""生成完整的HTML天气分析报告"""
from pyecharts.charts import Page
# 创建可视化图表
matplotlib_visualization(df) # 生成静态图片
tab = pyecharts_visualization(df) # 生成交互式图表
# 生成HTML报告
page = Page(layout=Page.DraggablePageLayout)
# 添加分析结论
analysis_text = f"""
<h1>全国主要城市天气分析报告</h1>
<h2>分析时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</h2>
<h3>数据概览:</h3>
<p>共分析 {len(df['城市'].unique())} 个城市,{len(df)} 条天气记录</p>
<p>时间范围:{df['日期'].min()} 至 {df['日期'].max()}</p>
<h3>主要发现:</h3>
<ul>
<li>平均温度最高的城市:{df.groupby('城市')['最高温度'].mean().idxmax()}</li>
<li>平均温度最低的城市:{df.groupby('城市')['最低温度'].mean().idxmin()}</li>
<li>最常见的天气状况:{df['天气'].value_counts().idxmax()}</li>
</ul>
"""
# 保存报告
with open(output_file, 'w', encoding='utf-8') as f:
f.write(analysis_text)
f.write('<h2>可视化分析</h2>')
f.write('<img src="weather_analysis_matplotlib.png" width="100%">')
f.write(tab.render_embed()) # 嵌入Pyecharts图表
print(f"天气分析报告已生成: {output_file}")
# 使用示例
if 'weather_df' in locals() and not weather_df.empty:
generate_weather_report(weather_df)
四、总结
本文介绍了:
如何使用Python爬取中国天气网的天气数据
使用pandas进行数据清洗和处理
使用Matplotlib和Pyecharts进行数据可视化
生成完整的天气分析报告
通过这个完整的流程,你可以轻松获取全国主要城市的天气数据,并进行专业的可视化分析。这种方法也可以应用于其他类似的数据分析和可视化场景。
最后:
希望你编程学习上不急不躁,按照计划有条不紊推进,把任何一件事做到极致,都是不容易的,加油,努力!相信自己!
文末福利
最后这里免费分享给大家一份Python全套学习资料,希望能帮到那些不满现状,想提升自己却又没有方向的朋友,也可以和我一起来学习交流呀。
包含编程资料、学习路线图、源代码、软件安装包等!【点击这里领取!】
① Python所有方向的学习路线图,清楚各个方向要学什么东西
② 100多节Python课程视频,涵盖必备基础、爬虫和数据分析
③ 100多个Python实战案例,学习不再是只会理论
④ 华为出品独家Python漫画教程,手机也能学习