mirror of
https://github.com/Zippland/Bubbles.git
synced 2026-02-27 08:01:16 +08:00
初始提交
This commit is contained in:
105
function/func_weather.py
Normal file
105
function/func_weather.py
Normal file
@@ -0,0 +1,105 @@
|
||||
import requests, json
|
||||
import logging
|
||||
import re # 导入正则表达式模块,用于提取数字
|
||||
|
||||
class Weather:
|
||||
def __init__(self, city_code: str) -> None:
|
||||
self.city_code = city_code
|
||||
self.LOG = logging.getLogger("Weather")
|
||||
|
||||
def _extract_temp(self, temp_str: str) -> str:
|
||||
"""从高温/低温字符串中提取温度数值"""
|
||||
if not temp_str:
|
||||
return ""
|
||||
# 匹配温度数字部分
|
||||
match = re.search(r"(\d+(?:\.\d+)?)", temp_str)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return ""
|
||||
|
||||
def get_weather(self, include_forecast: bool = False) -> str:
|
||||
# api地址
|
||||
url = 'http://t.weather.sojson.com/api/weather/city/'
|
||||
|
||||
# 网络请求,传入请求api+城市代码
|
||||
self.LOG.info(f"获取天气: {url + str(self.city_code)}")
|
||||
try:
|
||||
response = requests.get(url + str(self.city_code))
|
||||
self.LOG.info(f"获取天气成功: 状态码={response.status_code}")
|
||||
if response.status_code != 200:
|
||||
self.LOG.error(f"API返回非200状态码: {response.status_code}")
|
||||
return f"获取天气失败: 服务器返回状态码 {response.status_code}"
|
||||
except Exception as e:
|
||||
self.LOG.error(f"获取天气失败: {str(e)}")
|
||||
return "由于网络原因,获取天气失败"
|
||||
|
||||
try:
|
||||
# 将数据以json形式返回,这个d就是返回的json数据
|
||||
d = response.json()
|
||||
except json.JSONDecodeError as e:
|
||||
self.LOG.error(f"解析JSON失败: {str(e)}")
|
||||
return "获取天气失败: 返回数据格式错误"
|
||||
|
||||
# 当返回状态码为200,输出天气状况
|
||||
if(d.get('status') == 200):
|
||||
city_info = d.get('cityInfo', {})
|
||||
data = d.get('data', {})
|
||||
forecast = data.get('forecast', [])
|
||||
|
||||
if not forecast:
|
||||
self.LOG.warning("API返回的数据中没有forecast字段")
|
||||
return "获取天气失败: 数据不完整"
|
||||
|
||||
today = forecast[0] if forecast else {}
|
||||
|
||||
# 提取今日温度
|
||||
low_temp = self._extract_temp(today.get('low', ''))
|
||||
high_temp = self._extract_temp(today.get('high', ''))
|
||||
temp_range = f"{low_temp}~{high_temp}℃" if low_temp and high_temp else "N/A"
|
||||
|
||||
# 基础天气信息(当天)
|
||||
result = [
|
||||
f"城市:{city_info.get('parent', '')}/{city_info.get('city', '')}",
|
||||
f"时间:{d.get('time', '')} {today.get('week', '')}",
|
||||
f"温度:{temp_range}",
|
||||
f"天气:{today.get('type', '')}"
|
||||
]
|
||||
|
||||
# 如果需要预报信息,添加未来几天的天气
|
||||
if include_forecast and len(forecast) > 1:
|
||||
result.append("\n📅 天气预报:") # 修改标题
|
||||
# 显示未来4天的预报 (索引 1, 2, 3, 4)
|
||||
for day in forecast[1:5]: # 增加到4天预报
|
||||
# 提取星期的最后一个字
|
||||
week_day = day.get('week', '')
|
||||
week_char = week_day[-1] if week_day else ''
|
||||
|
||||
# 提取温度数值
|
||||
low_temp = self._extract_temp(day.get('low', ''))
|
||||
high_temp = self._extract_temp(day.get('high', ''))
|
||||
temp_range = f"{low_temp}~{high_temp}℃" if low_temp and high_temp else "N/A"
|
||||
|
||||
# 天气类型
|
||||
weather_type = day.get('type', '未知')
|
||||
|
||||
# 简化格式:只显示周几、温度范围和天气类型
|
||||
result.append(f"- 周{week_char} {temp_range} {weather_type}")
|
||||
|
||||
return "\n".join(result)
|
||||
else:
|
||||
return "获取天气失败"
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 设置测试用的日志配置
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 测试当天天气
|
||||
w = Weather("101010100") # 北京
|
||||
logger.info(w.get_weather()) # 不带预报
|
||||
|
||||
# 测试天气预报
|
||||
logger.info(w.get_weather(include_forecast=True)) # 带预报
|
||||
Reference in New Issue
Block a user