import requests import json from datetime import datetime class QWeatherAPI: def __init__(self, api_key): self.api_key = api_key self.base_url = "https://devapi.qweather.com/v7/weather/now" self.geo_url = "https://geoapi.qweather.com/v2/city/lookup" def verify_api_key(self): """ 验证API密钥是否有效 """ try: # 使用一个简单的城市ID测试API test_params = { "location": "101010100", # 北京的城市ID "key": self.api_key } response = requests.get(self.base_url, params=test_params) data = response.json() if data["code"] == "402": print("错误: API密钥无效或已过期") print("请检查:") print("1. API密钥是否正确") print("2. 是否使用了正确的API版本(开发版/正式版)") print("3. API密钥是否已过期") return False elif data["code"] == "200": return True else: print(f"API返回错误: {data['code']}") return False except Exception as e: print(f"验证API密钥时发生错误: {e}") return False def search_city(self, location_name, range=None, number=1): """ 搜索城市 :param location_name: 城市名称,如 "北京"、"上海" 等 :param range: 搜索范围,使用ISO 3166国家代码,如 "cn" :param number: 返回结果数量,范围1-20,默认1 :return: 城市信息列表 """ try: params = { "location": location_name, "key": self.api_key, "number": min(max(1, number), 20) # 确保number在1-20之间 } # 添加可选参数 if range: params["range"] = range response = requests.get(self.geo_url, params=params) response.raise_for_status() data = response.json() if data["code"] == "402": print(data) print("错误: API密钥无效或已过期") print("请检查:") print("1. API密钥是否正确") print("2. 是否使用了正确的API版本(开发版/正式版)") print("3. API密钥是否已过期") return None elif data["code"] != "200": print(f"城市查询API返回错误: {data['code']}") return None return data.get("location", []) except requests.exceptions.RequestException as e: print(f"请求错误: {e}") return None except json.JSONDecodeError as e: print(f"JSON解析错误: {e}") return None except Exception as e: print(f"未知错误: {e}") return None def get_weather(self, location): """ 获取实时天气数据 :param location: 城市ID或经纬度坐标,如 "101010100" 或 "116.41,39.92" :return: 天气数据字典 """ try: params = { "location": location, "key": self.api_key } response = requests.get(self.base_url, params=params) response.raise_for_status() # 检查HTTP错误 data = response.json() if data["code"] == "402": print("错误: API密钥无效或已过期") print("请检查:") print("1. API密钥是否正确") print("2. 是否使用了正确的API版本(开发版/正式版)") print("3. API密钥是否已过期") return None elif data["code"] != "200": print(f"API返回错误: {data['code']}") return None return data except requests.exceptions.RequestException as e: print(f"请求错误: {e}") return None except json.JSONDecodeError as e: print(f"JSON解析错误: {e}") return None except Exception as e: print(f"未知错误: {e}") return None def format_weather_data(data, city_info): """ 格式化天气数据为易读的格式 """ if not data or "now" not in data: return "无法获取天气数据" now = data["now"] return f""" 城市信息: 名称: {city_info['name']} 所属地区: {city_info.get('adm2', 'N/A')} 所属省份: {city_info.get('adm1', 'N/A')} 所属国家: {city_info.get('country', 'N/A')} 实时天气信息: 观测时间: {now['obsTime']} 温度: {now['temp']}°C 体感温度: {now['feelsLike']}°C 天气状况: {now['text']} 风向: {now['windDir']} 风力等级: {now['windScale']}级 风速: {now['windSpeed']}km/h 相对湿度: {now['humidity']}% 降水量: {now['precip']}mm 大气压强: {now['pressure']}hPa 能见度: {now['vis']}km 云量: {now['cloud']}% 露点温度: {now['dew']}°C """