【AI实战】Python开发AI天气预报助手全程指南:含完整代码实现

Python版AI天气预报助手开发指南(含完整代码)


一、背景

在当今数字化时代,人工智能(AI)正以前所未有的速度渗透到各个领域,从智能家居到自动驾驶,从医疗诊断到金融预测,AI 的影响力无处不在。作为一名对技术充满热情的探索者,我深知 AI 的潜力和价值,也意识到掌握 AI 技术对于个人和职业发展的重要性。因此,我决定深入实践 AI,通过实际项目的开发和应用,从最基础的API接入融入AI科技,提升自己的技术能力和对 AI 的理解。

在这个过程中,我选择了构建一个 AI 实现的天气助手 作为我的实践项目。结合传统冰冷的天气参数和暖心的大预言模型 AI 技术,打造一个能够自动解析城市编码、获取天气数据,并生成自然语言天气报告的智能系统,为用户提供更加贴心、便捷的天气服务。


二、技术选型

作为《穷鬼的回忆录》一书的作者,选型主要考虑的是免费! 免费! 免费!然后再考虑支持目前大热的deepseek模型,所以最后选择了和风天气无问芯穹的deepseek模型作为核心技术支撑,其中和风天气用于查询天气参数信息,无问芯穹用于根据查询的天气结果参数提供专业的报告。

  • 和风天气:作为国内领先的气象数据服务提供商,和风天气拥有丰富而精准的气象数据资源。我们利用其提供的API接口,可以轻松实现城市编码的查询以及获取城市当前的天气参数信息。通过调用和风天气的城市查询API,输入城市名称(支持中英文)或行政区划编码,即可快速获取对应的城市编码。这为后续的天气数据获取奠定了基础。在获取天气数据时,和风天气的实时天气API能够提供详细的气象信息,包括温度、湿度、风速、风向、降水概率等,且支持公制和英制两种单位制,满足不同用户的需求。
  • 无问芯穹的deepseek模型:在生成天气报告方面,我们选择了无问芯穹deepseek模型。该模型具备强大的自然语言处理能力,能够将结构化的天气数据转化为生动、自然的中文天气报告。通过精心设计的提示(Prompt),我们引导deepseek模型解析和风天气接口返回的数据,并生成包含穿衣建议和出行提示的个性化天气报告。这种结合AI技术的报告生成方式,不仅提升了用户体验,还为用户提供了更具实用性和参考价值的气象信息。

  • 三、AI实践

    1. 核心功能设计

  • 实时天气查询(温度/湿度/风速/天气状况),输入城市名称即可,简称或完整名称
  • 自然语言交互式应答,提供温馨的天气报告
  • 流式结果输出,减少时间等待,提升交互体验
  • 2. 环境准备

    (1)因和风天气无问芯穹接口调用都需要使用API密钥,因此需要分别去其官网注册账户并创建应用KEY:
    和风天气KEY
    无问芯穹KEY
    这两个网站都可以免费注册申请应用密钥,正常测试使用没啥问题的。
    获取和风天气 API 密钥(申请链接) 和无问芯穹 API 密钥(申请链接),并将其存储在当前目录下的 .env文件中。

    (2)安装Python环境依赖

    pip install openai python-dotenv requests
    

    其中:

  • openai:提供与OpenAI API交互的官方SDK(也适用于无问芯穹的deepseek模型接口调用),支持调用GPT、DALL·E等模型实现文本生成、图像创作等AI功能。
  • python-dotenv:用于从.env文件加载环境变量,简化敏感配置(如API密钥)的管理和隔离。
  • requests:简洁高效的HTTP请求库,支持API调用、数据爬取及服务端通信,具备自动内容解码和连接池管理。
  • 3. 关键代码实现

    3.1 系统架构与依赖
    (1)依赖库

    import os
    import json
    import requests
    from openai import OpenAI
    from dotenv import load_dotenv
    from requests.exceptions import RequestException
    
  • openaidotenv 用于与无问芯穹 API 进行交互及环境变量管理,为 AI 部分提供支持。
  • requests 主要用于和风天气 API 的 HTTP 请求,获取天气数据。
  • json 用于解析和处理 JSON 格式的响应数据,确保数据的正确性和可读性。
  • (2)环境变量初始化:

    load_dotenv()
    client = OpenAI(
        base_url="https://cloud.infini-ai.com/maas/v1",
        api_key=os.getenv("INFINI_AI_KEY")
    )
    

    使用dotenv加载.env配置文件,其中包含无问芯穹 API 的密钥INFINI_AI_KEY,将敏感信息与代码分离,符合安全规范。

    (3)环境变量文件: .env文件

    INFINI_AI_KEY=sk-**
    WEATHER_API_KEY=**
    

    3.2 核心函数
    (1)城市编码解析:

    def get_city_code(city: Union[str, int]) -> str:
        """
        智能解析城市编码(支持中英文城市名/行政区划编码)
        """
        api_key = os.getenv("WEATHER_API_KEY")
    
        # 判断是否为纯数字编码
        if isinstance(city, int) or city.isdigit():
            return str(city)
    
        # 调用和风天气城市查询 API
        geoapi_url = "https://geoapi.qweather.com/v2/city/lookup"
        params = {
            "location": city,
            "key": api_key,
            "range": "cn",
            "lang": "zh",
            "number": 1
        }
    
        try:
            response = requests.get(geoapi_url, params=params, timeout=10)
            response.raise_for_status()
    
            data = response.json()
            if data['code'] == '200' and data['location']:
                cid = data['location'][0]['id']
                return cid
    
            raise ValueError(f"未找到匹配的城市: {city}")
    
        except (RequestException, json.JSONDecodeError) as e:
            raise RuntimeError(f"城市查询接口异常: {str(e)}")
    
  • 功能描述:
  • 当输入值为纯数字时,直接返回该数字作为城市编码。
  • 若输入为城市名称(中文/英文),调用和风天气的城市查询 API,获取对应的城市编码。
  • 使用response.raise_for_status()确保 HTTP 请求成功,避免潜在的网络问题。
  • (2)天气数据获取:

    def get_weather(city: Union[str, int], unit: str = 'm') -> Dict:
        """
        获取和风天气实时数据(自动兼容 gzip 压缩)
        """
        api_key = os.getenv("WEATHER_API_KEY")
        city_id = get_city_code(city)
    
        url = "https://devapi.qweather.com/v7/weather/now"
        headers = {
            "Accept-Encoding": "gzip",
            "User-Agent": "PythonWeatherSDK/1.0"
        }
        params = {
            "location": city_id,
            "key": api_key,
            "lang": "zh",
            "unit": unit,
            "gzip": "true"
        }
    
        try:
            response = requests.get(url, headers=headers, params=params, timeout=15)
            response.raise_for_status()
            data = response.json()
    
            if data['code'] != '200':
                raise ValueError(f"[{data['code']}] {data.get('message', '未知错误')}")
    
            return data
    
        except RequestException as e:
            raise ConnectionError(f"天气接口请求失败: {str(e)}")
        except KeyError as e:
            raise RuntimeError(f"接口响应格式异常,缺失关键字段: {str(e)}")
    
  • 功能描述:
  • 使用和风天气的实时天气 API,获取指定城市的天气数据。
  • 自动处理gzip压缩的响应数据,减少网络传输的带宽占用。
  • 通过response.json()解析 JSON 格式的天气数据,并对关键字段进行校验。
  • (3)AI 天气报告生成:

    def generate_weather_report(city: str):
        """生成AI天气报告"""
        weather_data = get_weather(city)
        try:
            prompt = f"""作为专业气象学家,请解析以下和风天气接口查询结果并用中文生成{city}的天气报告:{weather_data}
                请包含穿衣建议和出行提示,用自然的口语化表达。"""
            print('助手查询:', prompt)
    
            response = client.chat.completions.create(
                model="deepseek-r1",
                messages=[{"role": "user", "content": prompt}],
                temperature=0.7,
                stream=True,
            )
    
            print('查询结果:\n')
            for chunk in response:
                if not chunk or not chunk.choices or len(chunk.choices) == 0:
                    continue
                chioce = chunk.choices[0]
                if chioce.finish_reason:
                    break
                text = chioce.delta.reasoning_content
                if not text:
                    text = chioce.delta.content
                print(text, end='', flush=True)
        except requests.exceptions.RequestException as e:
            print(f"[API Error] {str(e)}")
        except json.JSONDecodeError:
            print("[Error] Invalid response format")
    
  • 功能描述:
  • 调用无问芯穹的 AI 聊天 API,将天气数据转换为自然语言的天气报告。
  • 通过精心设计的提示(Prompt),引导 AI 模型生成包含穿衣建议和出行提示的个性化报告。
  • 使用stream=True实现流式响应,动态展示 AI 生成的天气报告内容,提升用户体验。
  • (4)亮点说明

    1. 智能城市编码解析
    2. 支持多种输入格式(中英文城市名、行政区划编码),提高了系统的灵活性与易用性。
    3. 利用和风天气的精准城市查询 API,确保城市编码的正确性,为后续天气查询提供基础。
    4. 高性能天气数据获取
    5. 自动兼容 gzip 压缩的 HTTP 响应,减少数据传输量,提高网络传输效率。
    6. 设定合理的超时时间(15秒),防止因网络问题导致的程序卡死,保证系统的稳定性。
    7. AI 自然语言生成
    8. 通过无问芯穹的 AI 对话模型,实现了从结构化数据(天气 API 响应)到自然语言报告的自动化转换。
    9. 提供了个性化的穿衣建议和出行提示,让天气信息更具实用性与参考价值。
    10. 流式响应的设计让用户能够实时看到 AI 的生成过程,增加了交互的趣味性。

    4.完整代码

  • 文件结构
  • .env
    天气助手.py
    
  • 天气助手.py源码
  • #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # @ProjectName: Learn
    # @Name: 天气助手.py
    # @Auth: arbboter
    # @Date: 2025/2/21-11:21
    # @Desc: 
    # @Ver : 0.0.0.1
    import os
    import json
    import requests
    from openai import OpenAI
    from dotenv import load_dotenv
    from requests.exceptions import RequestException
    from typing import Dict, Union
    
    # 配置无问芯穹API
    load_dotenv()
    client = OpenAI(
                base_url="https://cloud.infini-ai.com/maas/v1",
                api_key=os.getenv("INFINI_AI_KEY")
            )
    
    
    def get_city_code(city: Union[str, int]) -> str:
        """智能解析城市编码(支持中英文城市名/行政区划编码)"""
        api_key = os.getenv("WEATHER_API_KEY")
    
        # 判断是否为纯数字编码
        if isinstance(city, int) or city.isdigit():
            return str(city)
    
        # 调用和风天气城市查询API
        geoapi_url = "https://geoapi.qweather.com/v2/city/lookup"
        params = {
            "location": city,
            "key": api_key,
            "range": "cn",
            "lang": "zh",
            "number": 1
        }
    
        try:
            response = requests.get(geoapi_url, params=params, timeout=10)
            response.raise_for_status()
    
            data = response.json()
            if data['code'] == '200' and data['location']:
                cid = data['location'][0]['id']
                print(f"查询天气编码成功:{city}->{cid}")
                return cid
    
            raise ValueError(f"未找到匹配的城市: {city}")
    
        except (RequestException, json.JSONDecodeError) as e:
            raise RuntimeError(f"城市查询接口异常: {str(e)}")
    
    
    def get_weather(city: Union[str, int], unit: str = 'm') -> Dict:
        """
        获取和风天气实时数据(自动兼容gzip压缩)
    
        :param city: 支持城市ID/中文名称/英文名称
        :param unit: 单位制 m-公制 i-英制
        :return: 标准化天气数据字典
        """
        api_key = os.getenv("WEATHER_API_KEY")
        city_id = get_city_code(city)
    
        url = "https://devapi.qweather.com/v7/weather/now"
        headers = {
            "Accept-Encoding": "gzip",
            "User-Agent": "PythonWeatherSDK/1.0"
        }
        params = {
            "location": city_id,
            "key": api_key,
            "lang": "zh",
            "unit": unit,
            "gzip": "true"
        }
    
        try:
            # 处理响应
            response = requests.get(url, headers=headers, params=params, timeout=15)
            response.raise_for_status()
            data = response.json()
    
            # 处理API错误码
            if data['code'] != '200':
                raise ValueError(f"[{data['code']}] {data.get('message', '未知错误')}")
    
            print(f"查询{city}天气参数成功:{data}")
            # 标准化输出结构
            return data
    
        except RequestException as e:
            raise ConnectionError(f"天气接口请求失败: {str(e)}")
        except KeyError as e:
            raise RuntimeError(f"接口响应格式异常,缺失关键字段: {str(e)}")
    
    
    def generate_weather_report(city: str):
        """生成AI天气报告"""
        weather_data = get_weather(city)
        try:
            prompt = f"""作为专业气象学家,请解析以下和风天气接口查询结果并用中文生成{city}的天气报告:{weather_data}
                请包含穿衣建议和出行提示,用自然的口语化表达。"""
            print('助手查询:', prompt)
    
            response = client.chat.completions.create(
                model="deepseek-r1",
                messages=[{"role": "user", "content": prompt}],
                temperature=0.7,
                stream=True,
            )
    
            print('查询结果:\n')
            for chunk in response:
                if not chunk or not chunk.choices or len(chunk.choices) == 0:
                    continue
                chioce = chunk.choices[0]
                if chioce.finish_reason:
                    break
                text = chioce.delta.reasoning_content
                if not text:
                    text = chioce.delta.content
                print(text, end='', flush=True)
        except requests.exceptions.RequestException as e:
            print(f"[API Error] {str(e)}")
        except json.JSONDecodeError:
            print("[Error] Invalid response format")
    
    
    # 交互示例
    if __name__ == "__main__":
        city = input("作为您的AI天气助手,请输入您关心的城市名称:")
        # city = '深圳'
        generate_weather_report(city)
    
    
  • .env 配置内容
  • INFINI_AI_KEY=您的无问芯穹API密钥
    WEATHER_API_KEY=您的天气API密钥
    

    5.运行结果

    运行结果

    作为您的AI天气助手,请输入您关心的城市名称:广州
    查询天气编码成功:广州->101280101
    查询广州天气参数成功:{'code': '200', 'updateTime': '2025-02-21T16:36+08:00', 'fxLink': 'https://www.qweather.com/weather/guangzhou-101280101.html', 'now': {'obsTime': '2025-02-21T16:30+08:00', 'temp': '18', 'feelsLike': '16', 'icon': '104', 'text': '阴', 'wind360': '315', 'windDir': '西北风', 'windScale': '3', 'windSpeed': '13', 'humidity': '58', 'precip': '0.0', 'pressure': '1013', 'vis': '30', 'cloud': '96', 'dew': '11'}, 'refer': {'sources': ['QWeather'], 'license': ['CC BY-SA 4.0']}}
    助手查询: 作为专业气象学家,请解析以下和风天气接口查询结果并用中文生成广州的天气报告:{'code': '200', 'updateTime': '2025-02-21T16:36+08:00', 'fxLink': 'https://www.qweather.com/weather/guangzhou-101280101.html', 'now': {'obsTime': '2025-02-21T16:30+08:00', 'temp': '18', 'feelsLike': '16', 'icon': '104', 'text': '阴', 'wind360': '315', 'windDir': '西北风', 'windScale': '3', 'windSpeed': '13', 'humidity': '58', 'precip': '0.0', 'pressure': '1013', 'vis': '30', 'cloud': '96', 'dew': '11'}, 'refer': {'sources': ['QWeather'], 'license': ['CC BY-SA 4.0']}}
                请包含穿衣建议和出行提示,用自然的口语化表达。
    查询结果:【动态显示,思考过程及最终报告】
    [好的,我现在需要帮用户解析这个和风天气的接口查询结果,并生成广州的天气报告。首先,我得仔细看看用户提供的JSON数据,确保没有遗漏任何关键信息。数据里的code是200,说明请求成功,没问题。接下来要注意更新时间是2025年2月21日下午4点36分,但实际观测时间是下午4点30分,这可能对实时性有影响吗?不过用户没特别提到,可能暂时不用处理这个时间差。
    
    接下来是天气数据部分,现在温度是18度,体感温度16,阴天。图标]
    

    因为使用流式模式,生成报告时的交互比较友好,可以即时显示服务信息。

    作者:arbboter

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【AI实战】Python开发AI天气预报助手全程指南:含完整代码实现

    发表回复