Python爬取天气数据并进行可视化分析的完整指南

包含编程籽料、学习路线图、爬虫代码、安装包等!【点击领取】

本文将介绍如何使用Python爬取天气数据,并进行可视化分析。我们将使用中国天气网作为数据源,通过requests和BeautifulSoup进行数据爬取,然后使用pandas进行数据处理,最后使用matplotlib和pyecharts进行可视化展示。

一、爬取天气数据

  1. 准备工作
    首先安装必要的库:
pip install requests beautifulsoup4 pandas matplotlib pyecharts
  1. 爬虫代码实现
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)

二、数据可视化分析

  1. 使用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)
  1. 使用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漫画教程,手机也能学习

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值