在气象科研、环境分析、数据分析、毕业设计等场景中,高精度、长时间序列、免费可用的逐小时气象数据是刚需资源。
今天分享一款完全开源免费、无密钥限制、全球覆盖的气象数据神器——Open-Meteo,并附上可直接运行的Python完整代码,一键批量下载标准化逐小时数据,导出CSV,拿来即用!
一、Open-Meteo 是什么?
Open-Meteo 是一款非商用免费、开源透明、高精度的全球气象API服务,也是目前科研人员和数据分析爱好者最常用的免费气象数据平台之一,聚合 ECMWF、NOAA、德国DWD、法国气象局等全球顶级机构模型,最高分辨率可达 1km,数据可靠性强。
其支持温度、湿度、降水、气压、云量、风速风向、边界层高度、短波辐射等核心气象指标,覆盖绝大多数科研与分析场景,提供自定义任意时间段、任意经纬度点位数据下载。
二、本次Python代码核心功能
本脚本专为国内用户优化,自动适配北京时间(UTC+8),开箱即用,无需复杂配置。一键下载9类核心气象数据 – 包括气温、湿度、降雨、气压、云量、风速、风向、边界层高度、短波辐射。
| | | |
| | | |
| | | |
| | | |
| | boundary_layer_height [m] | |
| | shortwave_radiation [W/m²] | |
三、完整可运行Python代码
1. 环境依赖安装
运行代码前,先安装所需第三方库,终端执行以下命令:
pip install pandas openmeteo-requests requests-cache retry-requests
2. 完整源码(直接复制可用)
import pandas as pdimport openmeteo_requestsimport requests_cachefrom retry_requests import retry# 1. 初始化 Open-Meteo API 客户端,配置缓存与重试机制cache_session = requests_cache.CachedSession(".cache", expire_after=3600)retry_session = retry(cache_session, retries=5, backoff_factor=0.2)openmeteo = openmeteo_requests.Client(session=retry_session)def download_meteo_data( lat, lon, start_date_bj, end_date_bj, output_csv="meteo_data.csv"): # 2. 将输入的北京时间日期转换为 UTC 日期以适配 API start_dt_utc = pd.to_datetime(start_date_bj) - pd.Timedelta(hours=8) end_dt_utc = pd.to_datetime(end_date_bj) - pd.Timedelta(hours=8) # 3. 设置 API 请求参数 url = "https://archive-api.open-meteo.com/v1/archive" params = { "latitude": lat, "longitude": lon, "start_date": start_dt_utc.strftime("%Y-%m-%d"), "end_date": end_dt_utc.strftime("%Y-%m-%d"), "hourly": [ "temperature_2m", "relative_humidity_2m", "rain", "surface_pressure", "cloud_cover", "wind_speed_10m", "wind_direction_10m", "boundary_layer_height", "shortwave_radiation", ], "wind_speed_unit": "ms", "timezone": "auto", } print(f"正在请求数据,经度:{lon},纬度:{lat}...") responses = openmeteo.weather_api(url, params=params) response = responses[0] # 4. 解析小时数据 hourly = response.Hourly() start_timestamp = hourly.Time() end_timestamp = hourly.TimeEnd() interval = hourly.Interval() utc_time_range = pd.date_range( start=pd.to_datetime(start_timestamp, unit="s", utc=True), end=pd.to_datetime(end_timestamp, unit="s", utc=True), freq=pd.Timedelta(seconds=interval), inclusive="left", ) # 定义带单位的列名,提升数据可读性 col_temp = "temperature_2m [°C]" col_rh = "relative_humidity_2m [%]" col_rain = "rain [mm]" col_press = "surface_pressure [hPa]" col_cloud = "cloud_cover [%]" col_ws = "wind_speed_10m [m/s]" col_wd = "wind_direction_10m (10 m) [°]" col_pbl = "boundary_layer_height [m]" col_ghi = "shortwave_radiation [W/m²]" hourly_data = { "text_time_utc": utc_time_range, col_temp: hourly.Variables(0).ValuesAsNumpy(), col_rh: hourly.Variables(1).ValuesAsNumpy(), col_rain: hourly.Variables(2).ValuesAsNumpy(), col_press: hourly.Variables(3).ValuesAsNumpy(), col_cloud: hourly.Variables(4).ValuesAsNumpy(), col_ws: hourly.Variables(5).ValuesAsNumpy(), col_wd: hourly.Variables(6).ValuesAsNumpy(), col_pbl: hourly.Variables(7).ValuesAsNumpy(), col_ghi: hourly.Variables(8).ValuesAsNumpy(), } df = pd.DataFrame(data=hourly_data) # 5. UTC 转北京时间(UTC+8) df["Time (Beijing)"] = df["text_time_utc"].dt.tz_convert("Asia/Shanghai") df["Time (Beijing)"] = df["Time (Beijing)"].dt.tz_localize(None) df = df.drop(columns=["text_time_utc"]) # 将时间列调整至首列 cols = ["Time (Beijing)"] + [c for c in df.columns if c != "Time (Beijing)"] df = df[cols] # 6. 统一数据精度,保留三位小数 round_columns = { col_rh: 3, col_press: 3, col_ws: 3, col_wd: 3, } df = df.round(round_columns) # 7. 精准筛选北京时间范围内的数据 start_filter = pd.to_datetime(start_date_bj) end_filter = pd.to_datetime(end_date_bj) + pd.Timedelta(hours=23, minutes=59) df = df[(df["Time (Beijing)"] >= start_filter) & (df["Time (Beijing)"] <= end_filter)] # 8. 保存为 UTF-8 编码 CSV 文件 df.to_csv(output_csv, index=False, encoding="utf-8-sig") print("气象数据下载完成,已成功保存为CSV文件!")if __name__ == "__main__": # 可自定义修改:经纬度、起止时间、文件名称 LATITUDE = 30.6502 # 纬度(示例:成都) LONGITUDE = 104.068 # 经度(示例:成都) # 北京时间起止日期,格式固定 YYYY-MM-DD START_DATE_BJ = "2026-05-01" END_DATE_BJ = "2026-05-02" # 自动生成文件名称 OUTPUT_FILE = f"./{START_DATE_BJ}_to_{END_DATE_BJ}_hourly_meteo.csv" # 执行数据下载 download_meteo_data( lat=LATITUDE, lon=LONGITUDE, start_date_bj=START_DATE_BJ, end_date_bj=END_DATE_BJ, output_csv=OUTPUT_FILE )
增加/删减气象参数?
只需修改代码中 hourly 列表内的参数,按需增减指标即可。
四、自定义修改教程
代码无需大幅改动,只需修改底部 4个核心参数,即可适配任意地点和时间段:
示例:将经纬度替换为北京(39.9042, 116.4074),即可下载北京市逐小时气象数据。
📌 总结
Open-Meteo 凭借免费、高精度、开源、多维数据的优势,是替代付费气象API的最优选择之一。搭配本次优化后的Python脚本,无需复杂配置,零基础也能快速批量获取标准化逐小时气象数据,极大提升数据分析效率!