当前位置:首页>python>【Python进阶】你的私人气象专家:Python+免费API,精准指定经纬度的实况天气

【Python进阶】你的私人气象专家:Python+免费API,精准指定经纬度的实况天气

  • 2026-09-09 14:58:32
【Python进阶】你的私人气象专家:Python+免费API,精准指定经纬度的实况天气

还在为找天气预报API发愁?Open-Meteo 完全免费、无需注册、无需API Key,提供全球高精度气象数据。今天就用Python写一个“天气情报员”,输入经纬度,立刻返回温度、湿度、风速、天气现象等15项实况数据,并且全部转为中文!

🔍 Open-Meteo 是什么神器?

Open-Meteo 是一个开源、非商业免费的气象API,整合了欧洲中期天气预报中心(ECMWF)、德国气象局等多个权威数据源。相比其他商业API:

  • ✅ 完全免费,无需密钥
  • ✅ 提供实时、预报、历史数据,支持全球任意坐标
  • ✅ 高分辨率,更新频率高
  • ✅ 支持多种单位制(摄氏度、华氏度,m/s、km/h等)

💡 为什么自己写代码获取天气?

虽然手机天气App很多,但无法批量获取、无法嵌入自己的项目、数据维度有限。用Python脚本,你可以:

  • 🔧 集成到智能家居、农业监控、旅行规划系统
  • 📊 自动记录历史天气,分析气候变化
  • 📱 通过微信/钉钉机器人推送定制天气
  • 🎓 学习API调用、JSON解析、数据可视化

而今天这份代码,就是你迈出第一步的“钥匙”。

⚙️ 实现思路 & 核心代码解析

我们使用 requests 库调用 Open-Meteo 的 /v1/forecast 接口,并加入 current 参数一次性获取15种当前气象要素。然后对返回的JSON进行解析,将英文代码转换为易懂的中文(天气现象、风向、白天/夜晚)。

📌 请求参数说明

关键参数:current :指定需要哪些实时数据,例如 temperature_2m(温度)、wind_speed_10m(风速)、weather_code(天气代码)等。wind_speed_unit :强制风速单位为 m/s(也可改为 km/h)。timezone :设置为 Asia/Shanghai,返回的 time 字段自动转为北京时间。

🔄 中文化处理亮点

为了让输出结果一目了然,代码实现了三个“翻译器”:

  • 🌍 风向翻译
    将0~360度转为“北风、东北风……”等汉字。
  • ☁️ 天气代码翻译
    WMO标准代码(0~99)映射成“晴、小雨、雷暴”等中文。
  • 📋 字段名翻译
    将 temperature_2m 显示为“温度”,单位自动附加。

📷 运行效果抢先看

按照指定地点的经纬度,调用 get_current_weather(34.75, 117.25)  ,输出如下:

所有数值保留一位小数,风向同时显示度数和方位,非常直观!

🚀 进阶玩法:让天气“活”起来

拿到数据后,你可以做很多有趣的事:

  • 📧 结合 smtplib 每天给自己发天气邮件。
  • 📊 用 matplotlib 绘制气温变化曲线。
  • 🤖 接入企业微信/钉钉机器人,群内自动播报天气。
  • 🌾 农业监测:定时记录温湿度、降水量,辅助种植决策。

Open-Meteo 还支持历史数据、逐小时预报、海浪模型等,你甚至可以获取未来15天的日出日落时间。

🧩 完整代码(复制即用)

确保你的Python环境安装了 requests 库(pip install requests),然后运行以下代码:

import requestsdef wind_dir_to_text(degrees):    """将风向度数转换为中文方位"""    if degrees is None:        return "未知"    dirs = ["北风", "东北风", "东风", "东南风", "南风", "西南风", "西风", "西北风"]    idx = round(degrees / 45) % 8    return dirs[idx]def weather_code_to_text(code):    """将WMO天气代码转换为中文描述"""    # 参考 Open-Meteo 天气代码(基于 WMO)    weather_map = {        0: "晴",        1: "基本晴",        2: "局部多云",        3: "阴",        45: "雾",        48: "沉积雾",        51: "轻毛毛雨",        53: "中毛毛雨",        55: "浓毛毛雨",        56: "冻毛毛雨",        57: "强冻毛毛雨",        61: "小雨",        63: "中雨",        65: "大雨",        66: "冻雨",        67: "强冻雨",        71: "小雪",        73: "中雪",        75: "大雪",        77: "雪粒",        80: "小阵雨",        81: "中阵雨",        82: "大阵雨",        85: "小雪阵",        86: "大雪阵",        95: "雷暴",        96: "雷暴伴小冰雹",        99: "雷暴伴大冰雹",    }    return weather_map.get(code, f"未知({code})")def get_current_weather(lat, lon):    """获取指定经纬度的全部当前实况气象数据,输出中文"""    url = "https://api.open-meteo.com/v1/forecast"    params = {        "latitude": lat,        "longitude": lon,        "current": [            "temperature_2m",            "relative_humidity_2m",            "apparent_temperature",            "is_day",            "precipitation",            "rain",            "showers",            "snowfall",            "weather_code",            "cloud_cover",            "pressure_msl",            "surface_pressure",            "wind_speed_10m",            "wind_direction_10m",            "wind_gusts_10m"        ],        "wind_speed_unit": "ms",        "timezone": "Asia/Shanghai"    }    # 字段名中文映射(key -> 中文名称)    field_name_map = {        "temperature_2m": "温度",        "relative_humidity_2m": "相对湿度",        "apparent_temperature": "体感温度",        "is_day": "白天/夜晚",        "precipitation": "总降水量",        "rain": "雨量",        "showers": "阵雨量",        "snowfall": "降雪量",        "weather_code": "天气现象",        "cloud_cover": "云量",        "pressure_msl": "海平面气压",        "surface_pressure": "地表气压",        "wind_speed_10m": "风速",        "wind_direction_10m": "风向",        "wind_gusts_10m": "阵风风速",        "time": "数据时间"    }    # 单位映射    unit_map = {        "temperature_2m": "°C",        "relative_humidity_2m": "%",        "apparent_temperature": "°C",        "precipitation": "mm",        "rain": "mm",        "showers": "mm",        "snowfall": "cm",        "cloud_cover": "%",        "pressure_msl": "hPa",        "surface_pressure": "hPa",        "wind_speed_10m": "m/s",        "wind_gusts_10m": "m/s",        "wind_direction_10m": "",        "weather_code": "",        "is_day": "",        "time": ""    }    try:        response = requests.get(url, params=params)        response.raise_for_status()        data = response.json()        if "current" in data:            current = data["current"]            print(f"经纬度: {lat}, {lon}")            # 获取时区转换后的本地时间(API 返回的是 UTC 时间,但设置了 timezone 后 current 中的 time 已经是本地时间字符串)            print(f"数据时间: {current.get('time', 'N/A')}")            print("-" * 40)            for key, value in current.items():                # 跳过 time,已经单独打印                if key == "time":                    continue                # 获取中文名称                ch_name = field_name_map.get(key, key)                # 处理特殊值的转换                if key == "weather_code":                    value = weather_code_to_text(value)                    unit = ""                elif key == "is_day":                    value = "白天" if value == 1 else "夜晚"                    unit = ""                elif key == "wind_direction_10m":                    # 风向:同时显示度数和方位文字                    direction_text = wind_dir_to_text(value)                    value = f"{value}° ({direction_text})"                    unit = ""                else:                    unit = unit_map.get(key, "")                # 格式化数值(保留一位小数)                if isinstance(value, (int, float)) and key not in ["weather_code", "is_day"]:                    value = f"{value:.1f}"                print(f"{ch_name}: {value}{unit}".strip())        else:            print("响应中未找到 'current' 字段,原始返回:", data)    except requests.exceptions.RequestException as e:        print(f"网络请求错误: {e}")    except Exception as e:        print(f"解析数据时发生错误: {e}")# 调用示例:经度 117.25, 纬度 34.75get_current_weather(34.75, 117.25) 

💡 小提示: 经纬度从哪里找?打开百度地图或高德地图,点击任意位置即可看到坐标;或者搜索“经纬度查询”在线获取。修改代码最后一行即可查询你关心的城市!


📌 本文代码完全开源,如果对你有帮助,欢迎点赞、在看、分享,让更多人用Python玩转气象数据!

🌐 免费API🐍 零门槛代码🌍 全球天气

最新文章

随机文章