1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
| import requests import json from datetime import datetime
class WeatherBot: def __init__(self, api_key): self.api_key = api_key self.url_current = "https://devapi.qweather.com/v7/weather/now" self.url_forecast = "https://devapi.qweather.com/v7/weather/3d" self.url_air = "https://devapi.qweather.com/v7/air/now" self.city_cache = {} def get_city_id(self, city_name): """根据城市名获取城市ID(和风天气需要城市ID)""" if city_name in self.city_cache: return self.city_cache[city_name] city_map = { "北京": "101010100", "上海": "101020100", "广州": "101280101", "深圳": "101280601", "重庆": "101040100", "成都": "101270101", "杭州": "101210101", "武汉": "101200101", "南京": "101190101", "西安": "101110101", } if city_name in city_map: self.city_cache[city_name] = city_map[city_name] return city_map[city_name] url = "https://geoapi.qweather.com/v2/city/lookup" params = {'location': city_name, 'key': self.api_key} try: resp = requests.get(url, params=params, timeout=5) data = resp.json() if data.get('code') == '200' and data.get('location'): city_id = data['location'][0]['id'] self.city_cache[city_name] = city_id return city_id except Exception as e: print(f"查询城市ID失败:{e}") return city_name def get_weather(self, city): """获取当前天气""" city_id = self.get_city_id(city) params = { 'location': city_id, 'key': self.api_key, 'unit': 'm' } try: resp = requests.get(self.url_current, params=params, timeout=5) data = resp.json() if data.get('code') == '200': return self._format_current(data, city) else: return f"查询失败:错误码 {data.get('code')}" except requests.Timeout: return "❌ 请求超时,请检查网络" except requests.ConnectionError: return "❌ 网络连接失败" except Exception as e: return f"❌ 查询出错:{e}" def get_forecast(self, city): """获取天气预报""" city_id = self.get_city_id(city) params = { 'location': city_id, 'key': self.api_key } try: resp = requests.get(self.url_forecast, params=params, timeout=5) data = resp.json() if data.get('code') == '200': return self._format_forecast(data, city) else: return f"查询失败:错误码 {data.get('code')}" except Exception as e: return f"❌ 查询出错:{e}" def get_air_quality(self, city): """获取空气质量""" city_id = self.get_city_id(city) params = { 'location': city_id, 'key': self.api_key } try: resp = requests.get(self.url_air, params=params, timeout=5) data = resp.json() if data.get('code') == '200': return self._format_air(data, city) else: return None except: return None def _format_current(self, data, city): """格式化当前天气""" now = data['now'] temp = now['temp'] feels = now['feelsLike'] hum = now['humidity'] wind = now['windSpeed'] wind_dir = now['windDir'] weather = now['text'] vis = now['vis'] temp_diff = int(feels) - int(temp) temp_notice = "" if temp_diff <= -3: temp_notice = f"(体感比实际低{abs(temp_diff)}度,注意保暖!)" elif temp_diff >= 3: temp_notice = f"(体感比实际高{temp_diff}度)" report = f""" 🌍 {city} 当前天气 ━━━━━━━━━━━━━━━━━━ 🌡️ 温度: {temp}°C (体感{feels}°C){temp_notice} ☁️ 天气: {weather} 💧 湿度: {hum}% 💨 风速: {wind}km/h {wind_dir} 👁️ 能见度: {vis}km
💡 {self._get_advice(temp, weather, hum)} """ return report def _format_forecast(self, data, city): """格式化预报""" daily = data['daily'] result = f"\n🌍 {city} 未来3天预报\n━━━━━━━━━━━━━━━━━━\n" for day in daily: date = day['fxDate'] temp_max = day['tempMax'] temp_min = day['tempMin'] weather_day = day['textDay'] weather_night = day['textNight'] temp_range = int(temp_max) - int(temp_min) range_notice = " ⚠️温差大" if temp_range >= 15 else "" result += f"📅 {date}: {temp_min}°C ~ {temp_max}°C, {weather_day}/{weather_night}{range_notice}\n" return result def _format_air(self, data, city): """格式化空气质量""" now = data['now'] aqi = now.get('aqi', 'N/A') category = now.get('category', 'N/A') pm25 = now.get('pm2p5', 'N/A') advice = "" aqi_val = int(aqi) if aqi.isdigit() else 999 if aqi_val <= 50: advice = "✅ 空气优,适合户外运动" elif aqi_val <= 100: advice = "👍 空气良,可正常户外活动" elif aqi_val <= 150: advice = "⚠️ 轻度污染,减少户外运动" elif aqi_val <= 200: advice = "❌ 中度污染,建议室内活动" else: advice = "🚫 重度污染,避免外出" return f"\n🌫️ {city} 空气质量: AQI {aqi} ({category}) PM2.5: {pm25}\n {advice}" def _get_advice(self, temp, weather, hum): """根据天气给出建议""" advice = [] temp = int(temp) hum = int(hum) if temp < 0: advice.append("🥶 严寒,请穿羽绒服、戴帽子手套") elif temp < 5: advice.append("❄️ 天气寒冷,请穿羽绒服") elif temp < 10: advice.append("🧥 天冷,穿厚外套+毛衣") elif temp < 15: advice.append("🧣 天气较凉,建议穿外套") elif temp < 20: advice.append("👔 温度适中,可以穿长袖+薄外套") elif temp < 25: advice.append("👕 温度适宜,穿长袖即可") elif temp < 30: advice.append("🩳 天气偏热,穿短袖") elif temp < 35: advice.append("☀️ 天气炎热,注意防暑降温") else: advice.append("🔥 高温预警,尽量待在室内!") if '暴雨' in weather: advice.append("🌊 暴雨预警,非必要不出门!") elif '大雨' in weather: advice.append("🌧️ 大雨,出门一定带伞") elif '雨' in weather: advice.append("☂️ 有雨,记得带伞") if '雪' in weather: advice.append("⛸️ 有雪,注意防滑") if '雷' in weather: advice.append("⚡ 雷电预警,避免户外活动") if '雾' in weather or '霾' in weather: advice.append("😷 能见度低,开车注意安全") if '晴' in weather and temp > 20: advice.append("🏃 天气晴朗,适合户外活动") if hum > 80: advice.append("💧 湿度高,体感闷热") elif hum < 30: advice.append("🏜️ 空气干燥,多喝水保湿") return " | ".join(advice) if advice else "祝你今天愉快!😊" def daily_report(self, city): """生成每日天气报告(整合所有信息)""" report = "" report += self.get_weather(city) report += self.get_forecast(city) air = self.get_air_quality(city) if air: report += air return report
if __name__ == "__main__": API_KEY = "你的API_Key" bot = WeatherBot(API_KEY) print(bot.daily_report("重庆"))
|