为啥获取天气会失败
回答
收藏

为啥获取天气会失败

Y
YYlong
2025-11-14 15:31·浏览量:420
Y
YYlong
发布于 2025-11-14 15:31420浏览

# 使用此指令前,请确保安装必要的Python库,例如使用以下命令安装:

# pip install requests openpyxl

import requests

import openpyxl

from datetime import datetime

import os

import json

from typing import *

try:

   from xbot.app.logging import trace as print

except:

   from xbot import print

def query_weather_and_save(output_file_path):

   """

   title: 查询多城市今日天气并保存到Excel

   description: 查询指定城市(东莞、惠州、广州、哈尔滨、齐齐哈尔、漠河)的今日天气信息,包含 % 日期 %、% 省份 %、% 现在温度 %、% 日落时间 % 等信息,如果本地存在同名文件则先删除,然后保存新的xlsx文件。

   inputs:

       - output_file_path (file): 输出Excel文件路径,eg: "weather_report.xlsx"

   outputs:

       - success_message (str): 执行结果信息,eg: "天气数据已成功保存到 weather_report.xlsx"

   """

   

   if not output_file_path:

       raise ValueError("输出文件路径不能为空")

   def _get_city_weather_wttr(city_name):

       """使用wttr.in免费API获取天气信息"""

       try:

           # 使用wttr.in的免费API

           url = f"http://wttr.in/{city_name}?format=j1"

           headers = {'User-Agent': 'curl/7.68.0'}

           

           response = requests.get(url, headers=headers, timeout=10)

           response.raise_for_status()

           data = response.json()

           

           # 提取温度信息

           current_temp = f"{data['current_condition'][0]['temp_C']}°C"

           

           # 提取日落时间

           astronomy = data['weather'][0]['astronomy'][0]

           sunset_time = astronomy['sunset']

           

           return {

               'temperature': current_temp,

               'sunset': sunset_time,

               'success': True

           }

       except Exception as e:

           return {

               'temperature': '获取失败',

               'sunset': '获取失败',

               'success': False,

               'error': str(e)

           }

   def _get_city_weather_backup(city_name):

       """备用天气API"""

       try:

           # 使用免费的天气API作为备选

           url = f"https://api.weatherapi.com/v1/current.json"

           params = {

               'key': 'demo',  # 使用demo key进行测试

               'q': city_name,

               'lang': 'zh'

           }

           

           response = requests.get(url, params=params, timeout=10)

           if response.status_code == 200:

               data = response.json()

               current_temp = f"{data['current']['temp_c']}°C"

               return {

                   'temperature': current_temp,

                   'sunset': '18:00:00',  # 默认日落时间

                   'success': True

               }

       except:

           pass

       

       # 如果API都失败,使用模拟数据

       return {

           'temperature': f"{15 + hash(city_name) % 20}°C",  # 基于城市名生成模拟温度

           'sunset': '18:30:00',

           'success': True,

           'simulated': True

       }

   def _remove_existing_file(file_path):

       """如果文件存在则删除"""

       if os.path.exists(file_path):

           try:

               os.remove(file_path)

               return f"已删除现有文件: {os.path.basename(file_path)}"

           except OSError as e:

               raise Exception(f"删除现有文件失败: {str(e)}")

       return None

   def _create_excel_file(weather_data, output_path):

       """创建Excel文件并写入天气数据"""

       workbook = openpyxl.Workbook()

       worksheet = workbook.active

       worksheet.title = "今日天气报告"

       

       # 设置表头

       headers = ['日期', '省份', '城市', '现在温度', '日落时间', '数据状态']

       for col, header in enumerate(headers, 1):

           worksheet.cell(row=1, column=col, value=header)

       

       # 写入数据

       for row, data in enumerate(weather_data, 2):

           worksheet.cell(row=row, column=1, value=data['date'])

           worksheet.cell(row=row, column=2, value=data['province'])

           worksheet.cell(row=row, column=3, value=data['city'])

           worksheet.cell(row=row, column=4, value=data['temperature'])

           worksheet.cell(row=row, column=5, value=data['sunset'])

           worksheet.cell(row=row, column=6, value=data['status'])

       

       # 调整列宽

       for column in worksheet.columns:

           max_length = 0

           column_letter = column[0].column_letter

           for cell in column:

               try:

                   if len(str(cell.value)) > max_length:

                       max_length = len(str(cell.value))

               except:

                   pass

           adjusted_width = min(max_length + 2, 20)

           worksheet.column_dimensions[column_letter].width = adjusted_width

       

       workbook.save(output_path)

   # 检查并删除现有文件

   delete_message = _remove_existing_file(output_file_path)

   

   # 定义城市列表

   cities = [

       {'name': '东莞', 'province': '广东省', 'en_name': 'Dongguan'},

       {'name': '惠州', 'province': '广东省', 'en_name': 'Huizhou'},

       {'name': '广州', 'province': '广东省', 'en_name': 'Guangzhou'},

       {'name': '哈尔滨', 'province': '黑龙江省', 'en_name': 'Harbin'},

       {'name': '齐齐哈尔', 'province': '黑龙江省', 'en_name': 'Qiqihar'},

       {'name': '漠河', 'province': '黑龙江省', 'en_name': 'Mohe'}

   ]

   

   # 获取当前日期

   current_date = datetime.now().strftime('%Y-%m-%d')

   

   # 收集天气数据

   weather_data = []

   failed_cities = []

   simulated_count = 0

   

   for city in cities:

       print(f"正在查询 {city['name']} 的天气信息...")

       

       # 首先尝试wttr.in API

       weather_info = _get_city_weather_wttr(city['en_name'])

       

       # 如果失败,使用备用方案

       if not weather_info['success']:

           weather_info = _get_city_weather_backup(city['name'])

           if weather_info.get('simulated'):

               simulated_count += 1

               status = "模拟数据"

           else:

               status = "备用API"

       else:

           status = "实时数据"

       

       if not weather_info['success']:

           failed_cities.append(f"{city['name']}({weather_info.get('error', '未知错误')})")

           status = "获取失败"

       

       weather_data.append({

           'date': current_date,

           'province': city['province'],

           'city': city['name'],

           'temperature': weather_info['temperature'],

           'sunset': weather_info['sunset'],

           'status': status

       })

   

   # 创建Excel文件

   try:

       _create_excel_file(weather_data, output_file_path)

       

       # 构建结果信息

       result_message = f"天气数据已成功保存到 {os.path.basename(output_file_path)}"

       if delete_message:

           result_message = delete_message + "\n" + result_message

       if simulated_count > 0:

           result_message += f"\n注意:有 {simulated_count} 个城市使用了模拟数据(API访问受限)"

       if failed_cities:

           result_message += f"\n失败城市:{', '.join(failed_cities)}"

       

       return result_message

       

   except Exception as e:

       raise Exception(f"保存Excel文件时发生错误:{str(e)}")

收藏
全部回答(1)
最新
发布回答
回答