feat: add multi-source weather data collector with OpenWeatherMap, Visual Crossing, and NOAA METAR support.

This commit is contained in:
2569718930@qq.com
2026-02-07 22:41:44 +08:00
parent 463d3e3838
commit 0d98b35e43
2 changed files with 16 additions and 2 deletions
+6 -1
View File
@@ -130,6 +130,7 @@ def start_bot():
weather_data = weather.fetch_all_sources(city_name, lat=coords["lat"], lon=coords["lon"]) weather_data = weather.fetch_all_sources(city_name, lat=coords["lat"], lon=coords["lon"])
msg_lines = [f"📍 <b>{city_name.title()} 天气详情</b>"] msg_lines = [f"📍 <b>{city_name.title()} 天气详情</b>"]
msg_lines.append(f"⏱️ 生成时间: {datetime.now().strftime('%H:%M:%S')}")
msg_lines.append("" * 20) msg_lines.append("" * 20)
open_meteo = weather_data.get("open-meteo", {}) open_meteo = weather_data.get("open-meteo", {})
@@ -162,7 +163,11 @@ def start_bot():
if obs: if obs:
try: try:
obs_dt = datetime.fromisoformat(obs.replace("Z", "+00:00")) obs_dt = datetime.fromisoformat(obs.replace("Z", "+00:00"))
obs_str = obs_dt.strftime("%H:%M UTC") # 如果有 Open-Meteo 的时区偏移,则转换
utc_offset = open_meteo.get("utc_offset", 0)
from datetime import timezone, timedelta
local_obs_dt = obs_dt.astimezone(timezone(timedelta(seconds=utc_offset)))
obs_str = local_obs_dt.strftime("%H:%M") + " (当地)"
except: except:
obs_str = obs[:16] obs_str = obs[:16]
else: else:
+10 -1
View File
@@ -1,5 +1,6 @@
import requests import requests
import re import re
import time
from typing import Optional, Dict, List from typing import Optional, Dict, List
from datetime import datetime, timedelta from datetime import datetime, timedelta
from loguru import logger from loguru import logger
@@ -228,9 +229,15 @@ class WeatherDataCollector:
"ids": icao, "ids": icao,
"format": "json", "format": "json",
"hours": 3, # 获取最近3小时的观测 "hours": 3, # 获取最近3小时的观测
"_t": int(time.time()), # 禁用缓存
} }
response = self.session.get(url, params=params, timeout=self.timeout) response = self.session.get(
url,
params=params,
headers={"Cache-Control": "no-cache", "Pragma": "no-cache"},
timeout=self.timeout
)
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
@@ -319,6 +326,7 @@ class WeatherDataCollector:
"daily": "temperature_2m_max,apparent_temperature_max", "daily": "temperature_2m_max,apparent_temperature_max",
"timezone": "auto", "timezone": "auto",
"forecast_days": forecast_days, "forecast_days": forecast_days,
"_t": int(time.time()), # 禁用缓存,强制刷新
} }
# 对于美国市场,使用华氏度 # 对于美国市场,使用华氏度
@@ -328,6 +336,7 @@ class WeatherDataCollector:
response = self.session.get( response = self.session.get(
url, url,
params=params, params=params,
headers={"Cache-Control": "no-cache", "Pragma": "no-cache"},
timeout=self.timeout, timeout=self.timeout,
) )
response.raise_for_status() response.raise_for_status()