最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python編寫一個每日天氣提醒

 更新時間:2025年10月27日 09:06:06   作者:閑人編程  
在這個快節(jié)奏的時代,一個小小的貼心舉動往往能帶來意想不到的溫暖,本文就將教你如何使用Python構建一個自動化的每日天氣提醒系統(tǒng),有需要的可以參考下

1. 引言

在這個快節(jié)奏的時代,一個小小的貼心舉動往往能帶來意想不到的溫暖。想象一下,每天清晨,你的女朋友都能收到一條溫馨的天氣提醒,不僅包含準確的天氣信息,還有你親自編寫的暖心提示——這樣的關懷是不是很讓人心動?

本文就將教你如何使用Python構建一個自動化的每日天氣提醒系統(tǒng)。這個系統(tǒng)不僅實用,更重要的是它融入了你的個人情感,讓技術變得有溫度。無論你是編程新手還是有經驗的開發(fā)者,都能通過本文學會如何將技術轉化為貼心的浪漫工具。

2. 系統(tǒng)設計與功能規(guī)劃

2.1 系統(tǒng)架構設計

在開始編碼之前,讓我們先來規(guī)劃整個系統(tǒng)的架構。我們的天氣提醒系統(tǒng)需要包含以下幾個核心模塊:

2.2 核心功能特性

我們的天氣提醒系統(tǒng)將實現以下特色功能:

  • 精準天氣信息:獲取實時天氣、溫度、濕度、風速等詳細信息
  • 智能穿衣建議:根據溫度自動生成合適的穿衣建議
  • 個性化關懷提示:結合天氣情況提供貼心的生活建議
  • 多平臺支持:支持微信、郵件、短信等多種發(fā)送方式
  • 定時發(fā)送:在指定時間自動發(fā)送提醒
  • 異常處理:網絡異?;蚍詹豢捎脮r的備用方案

2.3 技術選型

  • 天氣數據源:使用和風天氣、OpenWeatherMap等免費API
  • 消息發(fā)送:使用SMTP協(xié)議發(fā)送郵件,或itchat庫發(fā)送微信
  • 定時任務:使用APScheduler庫管理定時任務
  • 數據存儲:使用SQLite存儲配置和歷史記錄
  • 配置管理:使用配置文件或環(huán)境變量管理敏感信息

3. 準備工作與環(huán)境配置

3.1 申請?zhí)鞖釧PI服務

首先,我們需要選擇一個天氣數據提供商。這里以和風天氣(免費版)為例:

  • 訪問和風天氣官網注冊賬號
  • 創(chuàng)建應用,獲取API Key
  • 了解API調用方式和返回數據格式

其他可選天氣服務:

  • OpenWeatherMap(免費版有限制)
  • 心知天氣
  • 阿里云天氣API

3.2 安裝必要的Python庫

pip install requests apscheduler python-dotenv sqlalchemy

如果需要微信支持,還需要安裝:

pip install itchat-uos

3.3 環(huán)境變量配置

創(chuàng)建.env文件來存儲敏感信息:

# 天氣API配置
WEATHER_API_KEY=你的和風天氣API_KEY
WEATHER_CITY=北京

# 郵箱配置(用于發(fā)送郵件提醒)
EMAIL_HOST=smtp.qq.com
EMAIL_PORT=587
EMAIL_USER=你的郵箱@qq.com
EMAIL_PASSWORD=你的郵箱授權碼

# 接收方配置
RECIPIENT_EMAIL=女朋友的郵箱@gmail.com
RECIPIENT_NAME=親愛的

4. 核心模塊實現

4.1 天氣數據獲取模塊

import requests
import json
from datetime import datetime, timedelta
import logging
from typing import Dict, List, Optional

class WeatherService:
    """天氣服務類,負責獲取和處理天氣數據"""
    
    def __init__(self, api_key: str, city: str):
        """
        初始化天氣服務
        
        Args:
            api_key: 和風天氣API Key
            city: 城市名稱
        """
        self.api_key = api_key
        self.city = city
        self.base_url = "https://devapi.qweather.com/v7"
        self.logger = logging.getLogger(__name__)
        
    def get_city_location(self) -> Optional[Dict]:
        """獲取城市位置信息(城市ID、坐標等)"""
        url = f"{self.base_url}/weather/now"
        params = {
            'location': self.city,
            'key': self.api_key
        }
        
        try:
            response = requests.get(url, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()
            
            if data['code'] == '200':
                # 從返回數據中提取位置信息
                location_info = {
                    'city': data.get('location', [{}])[0].get('name', self.city),
                    'id': data.get('location', [{}])[0].get('id', ''),
                    'lat': data.get('location', [{}])[0].get('lat', ''),
                    'lon': data.get('location', [{}])[0].get('lon', '')
                }
                return location_info
            else:
                self.logger.error(f"獲取位置信息失敗: {data.get('message', '未知錯誤')}")
                return None
                
        except requests.exceptions.RequestException as e:
            self.logger.error(f"網絡請求失敗: {str(e)}")
            return None
        except Exception as e:
            self.logger.error(f"獲取位置信息異常: {str(e)}")
            return None
    
    def get_current_weather(self) -> Optional[Dict]:
        """獲取當前天氣情況"""
        url = f"{self.base_url}/weather/now"
        params = {
            'location': self.city,
            'key': self.api_key,
            'lang': 'zh'  # 中文返回
        }
        
        try:
            response = requests.get(url, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()
            
            if data['code'] == '200':
                weather_data = data['now']
                return {
                    'temp': weather_data.get('temp', 'N/A'),  # 溫度
                    'feels_like': weather_data.get('feelsLike', 'N/A'),  # 體感溫度
                    'text': weather_data.get('text', 'N/A'),  # 天氣狀況文字
                    'wind_scale': weather_data.get('windScale', 'N/A'),  # 風力等級
                    'wind_dir': weather_data.get('windDir', 'N/A'),  # 風向
                    'humidity': weather_data.get('humidity', 'N/A'),  # 濕度
                    'precip': weather_data.get('precip', '0'),  # 降水量
                    'vis': weather_data.get('vis', 'N/A'),  # 能見度
                    'pressure': weather_data.get('pressure', 'N/A'),  # 氣壓
                    'update_time': weather_data.get('obsTime', '')  # 更新時間
                }
            else:
                self.logger.error(f"獲取當前天氣失敗: {data.get('message', '未知錯誤')}")
                return None
                
        except requests.exceptions.RequestException as e:
            self.logger.error(f"獲取當前天氣網絡請求失敗: {str(e)}")
            return None
        except Exception as e:
            self.logger.error(f"獲取當前天氣異常: {str(e)}")
            return None
    
    def get_daily_forecast(self, days: int = 3) -> Optional[List[Dict]]:
        """獲取多日天氣預報"""
        url = f"{self.base_url}/weather/{days}d"
        params = {
            'location': self.city,
            'key': self.api_key,
            'lang': 'zh'
        }
        
        try:
            response = requests.get(url, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()
            
            if data['code'] == '200':
                forecast_list = []
                for day_data in data.get('daily', []):
                    forecast = {
                        'date': day_data.get('fxDate', ''),
                        'temp_max': day_data.get('tempMax', 'N/A'),
                        'temp_min': day_data.get('tempMin', 'N/A'),
                        'text_day': day_data.get('textDay', 'N/A'),
                        'text_night': day_data.get('textNight', 'N/A'),
                        'wind_scale_day': day_data.get('windScaleDay', 'N/A'),
                        'humidity': day_data.get('humidity', 'N/A'),
                        'precip': day_data.get('precip', '0'),
                        'uv_index': day_data.get('uvIndex', 'N/A')
                    }
                    forecast_list.append(forecast)
                return forecast_list
            else:
                self.logger.error(f"獲取天氣預報失敗: {data.get('message', '未知錯誤')}")
                return None
                
        except requests.exceptions.RequestException as e:
            self.logger.error(f"獲取天氣預報網絡請求失敗: {str(e)}")
            return None
        except Exception as e:
            self.logger.error(f"獲取天氣預報異常: {str(e)}")
            return None
    
    def get_weather_warning(self) -> Optional[List[Dict]]:
        """獲取天氣預警信息"""
        url = f"{self.base_url}/warning/now"
        params = {
            'location': self.city,
            'key': self.api_key,
            'lang': 'zh'
        }
        
        try:
            response = requests.get(url, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()
            
            if data['code'] == '200':
                warnings = []
                for warning in data.get('warning', []):
                    warning_info = {
                        'type': warning.get('type', ''),
                        'level': warning.get('level', ''),
                        'title': warning.get('title', ''),
                        'text': warning.get('text', '')
                    }
                    warnings.append(warning_info)
                return warnings
            else:
                # 沒有預警信息是正常情況
                return []
                
        except Exception as e:
            self.logger.warning(f"獲取天氣預警信息失敗: {str(e)}")
            return []

4.2 智能分析與建議生成模塊

class WeatherAnalyzer:
    """天氣分析器,根據天氣數據生成智能建議"""
    
    def __init__(self):
        self.advice_templates = {
            'dressing': self._get_dressing_advice,
            'umbrella': self._get_umbrella_advice,
            'outdoor': self._get_outdoor_advice,
            'health': self._get_health_advice,
            'travel': self._get_travel_advice
        }
    
    def analyze_temperature(self, temp: int) -> Dict[str, str]:
        """分析溫度并給出建議"""
        temp = int(temp)
        
        if temp >= 30:
            level = "炎熱"
            feeling = "今天天氣炎熱,注意防暑降溫"
        elif temp >= 25:
            level = "溫暖"
            feeling = "今天天氣溫暖,適合戶外活動"
        elif temp >= 15:
            level = "舒適"
            feeling = "今天天氣舒適,是出行的好日子"
        elif temp >= 5:
            level = "涼爽"
            feeling = "今天天氣涼爽,記得適當添衣"
        elif temp >= 0:
            level = "寒冷"
            feeling = "今天天氣寒冷,注意保暖"
        else:
            level = "嚴寒"
            feeling = "今天天氣嚴寒,盡量減少外出"
            
        return {'level': level, 'feeling': feeling}
    
    def _get_dressing_advice(self, temp: int, weather_text: str) -> str:
        """生成穿衣建議"""
        temp = int(temp)
        
        if "雨" in weather_text:
            rain_note = "有雨,建議穿防水的衣物"
        else:
            rain_note = ""
            
        if temp >= 28:
            return f"?? 輕薄夏裝(短袖、裙子){rain_note}"
        elif temp >= 24:
            return f"?? 夏季服裝(短袖、薄長褲){rain_note}"
        elif temp >= 18:
            return f"?? 春秋過渡裝(長袖T恤、薄外套){rain_note}"
        elif temp >= 12:
            return f"?? 春秋裝(長袖、薄毛衣、外套){rain_note}"
        elif temp >= 6:
            return f"?? 初冬裝(毛衣、厚外套){rain_note}"
        elif temp >= 0:
            return f"?? 冬裝(羽絨服、厚毛衣){rain_note}"
        else:
            return f"?? 厚冬裝(加厚羽絨服、保暖內衣){rain_note}"
    
    def _get_umbrella_advice(self, weather_text: str, precip: float) -> str:
        """生成雨具建議"""
        precip = float(precip)
        
        if "雨" in weather_text or precip > 0:
            if precip > 10:
                return "?? 今天有大雨,一定要帶傘,建議穿雨鞋"
            elif precip > 5:
                return "? 今天有中雨,記得帶傘"
            else:
                return "??? 今天有小雨,建議帶傘"
        else:
            return "?? 今天無雨,可以不用帶傘"
    
    def _get_outdoor_advice(self, weather_text: str, temp: int, wind_scale: str) -> str:
        """生成戶外活動建議"""
        temp = int(temp)
        
        advice = []
        
        # 溫度適宜性
        if 18 <= temp <= 26:
            advice.append("今天的溫度非常適合戶外活動")
        elif temp > 30:
            advice.append("天氣炎熱,建議在陰涼處活動")
        elif temp < 5:
            advice.append("天氣較冷,戶外活動請注意保暖")
        
        # 天氣狀況
        if "晴" in weather_text:
            advice.append("陽光很好,適合散步和運動")
        elif "雨" in weather_text:
            advice.append("有雨,建議室內活動")
        elif "云" in weather_text:
            advice.append("多云天氣,適合各種戶外活動")
        elif "雪" in weather_text:
            advice.append("下雪天,注意防滑")
            
        # 風力影響
        if int(wind_scale) >= 6:
            advice.append("今天風較大,注意安全")
            
        return "。".join(advice) if advice else "今天天氣平穩(wěn),按計劃活動即可"
    
    def _get_health_advice(self, temp: int, humidity: int, uv_index: str) -> str:
        """生成健康建議"""
        temp = int(temp)
        humidity = int(humidity)
        
        advice = []
        
        # 溫度相關
        if temp >= 30:
            advice.append("天氣炎熱,注意補充水分,預防中暑")
        elif temp <= 0:
            advice.append("天氣寒冷,注意保暖,預防感冒")
            
        # 濕度相關
        if humidity >= 80:
            advice.append("濕度較高,注意防潮")
        elif humidity <= 30:
            advice.append("空氣干燥,注意保濕")
            
        # 紫外線
        if uv_index in ['5', '6', '7']:
            advice.append("紫外線中等,建議使用防曬霜")
        elif uv_index in ['8', '9', '10']:
            advice.append("紫外線強,需要做好防曬措施")
        elif uv_index in ['11', '12', '13', '14', '15']:
            advice.append("紫外線很強,盡量避免長時間在陽光下")
            
        return "。".join(advice) if advice else "今天天氣條件對健康影響較小"
    
    def _get_travel_advice(self, weather_text: str, vis: str) -> str:
        """生成出行建議"""
        advice = []
        
        if "雨" in weather_text:
            advice.append("雨天路滑,開車請減速慢行")
        elif "雪" in weather_text:
            advice.append("雪天路滑,建議使用公共交通工具")
        elif "霧" in weather_text:
            advice.append("有霧,能見度較低,注意行車安全")
            
        if vis and int(vis) < 1:
            advice.append("能見度很低,出行請?zhí)貏e注意安全")
        elif vis and int(vis) < 5:
            advice.append("能見度一般,小心駕駛")
            
        return "。".join(advice) if advice else "今天出行條件良好"
    
    def generate_comprehensive_advice(self, weather_data: Dict) -> Dict[str, str]:
        """生成綜合建議"""
        temp = int(weather_data.get('temp', 20))
        weather_text = weather_data.get('text', '')
        precip = float(weather_data.get('precip', 0))
        wind_scale = weather_data.get('wind_scale', '1')
        humidity = int(weather_data.get('humidity', 50))
        uv_index = weather_data.get('uv_index', '3')
        vis = weather_data.get('vis', '10')
        
        return {
            'temperature_analysis': self.analyze_temperature(temp),
            'dressing': self._get_dressing_advice(temp, weather_text),
            'umbrella': self._get_umbrella_advice(weather_text, precip),
            'outdoor': self._get_outdoor_advice(weather_text, temp, wind_scale),
            'health': self._get_health_advice(temp, humidity, uv_index),
            'travel': self._get_travel_advice(weather_text, vis)
        }

4.3 個性化消息生成模塊

import random
from datetime import datetime

class MessageGenerator:
    """消息生成器,創(chuàng)建個性化的天氣提醒消息"""
    
    def __init__(self, recipient_name: str):
        self.recipient_name = recipient_name
        self.greetings = [
            "早安,{}!新的一天開始啦",
            "早上好,{}!愿你有美好的一天",
            "{},醒來了嗎?來看看今天的天氣吧",
            "嗨,{}!今天也要加油哦",
            "{},新的一天充滿新的可能"
        ]
        
        self.closing_remarks = [
            "記得按時吃飯,愛你??",
            "不管天氣如何,我的關心永遠不變??",
            "今天也要開開心心的哦??",
            "記得想我,就像我想你一樣??",
            "愿你的一天像陽光一樣燦爛?"
        ]
        
        self.special_date_remarks = {
            'anniversary': "今天是我們的紀念日,晚上有驚喜哦??",
            'birthday': "生日快樂!我的小公主??",
            'valentine': "情人節(jié)快樂!我的愛人??",
            'weekend': "周末愉快!我們出去約會吧??"
        }
    
    def _check_special_date(self) -> Optional[str]:
        """檢查是否是特殊日期"""
        today = datetime.now()
        
        # 這里可以添加你們的特殊日期
        special_dates = {
            # 'anniversary': datetime(2024, 2, 14),  # 紀念日示例
            # 'birthday': datetime(2024, 3, 8),      # 生日示例
        }
        
        for occasion, date in special_dates.items():
            if today.month == date.month and today.day == date.day:
                return occasion
                
        # 檢查周末
        if today.weekday() >= 5:  # 5=周六, 6=周日
            return 'weekend'
            
        return None
    
    def generate_message(self, weather_data: Dict, advice_data: Dict, 
                        forecast_data: List[Dict] = None) -> str:
        """生成完整的天氣提醒消息"""
        
        # 問候語
        greeting = random.choice(self.greetings).format(self.recipient_name)
        
        # 當前天氣摘要
        current_temp = weather_data.get('temp', 'N/A')
        weather_text = weather_data.get('text', 'N/A')
        temp_analysis = advice_data['temperature_analysis']
        
        weather_summary = (
            f"??? 當前溫度:{current_temp}°C({temp_analysis['level']})\n"
            f"??? 天氣狀況:{weather_text}\n"
            f"?? 體感溫度:{weather_data.get('feels_like', 'N/A')}°C\n"
            f"?? 濕度:{weather_data.get('humidity', 'N/A')}%\n"
            f"??? 風力:{weather_data.get('wind_scale', 'N/A')}級 {weather_data.get('wind_dir', '')}"
        )
        
        # 生活建議
        advice_section = (
            f"\n?? 今日生活建議:\n"
            f"{advice_data['dressing']}\n"
            f"{advice_data['umbrella']}\n"
            f"{advice_data['outdoor']}\n"
            f"{advice_data['health']}\n"
            f"{advice_data['travel']}"
        )
        
        # 天氣預報
        forecast_section = ""
        if forecast_data:
            forecast_section = "\n\n?? 未來三天預報:\n"
            for i, forecast in enumerate(forecast_data[:3]):
                date_str = forecast['date'][5:]  # 只顯示月日
                day_name = "今天" if i == 0 else "明天" if i == 1 else "后天"
                forecast_section += (
                    f"{day_name}({date_str}):{forecast['text_day']},"
                    f"{forecast['temp_min']}~{forecast['temp_max']}°C\n"
                )
        
        # 預警信息
        warning_section = ""
        warnings = weather_data.get('warnings', [])
        if warnings:
            warning_section = "\n?? 天氣預警:\n"
            for warning in warnings:
                warning_section += f"{warning['title']}:{warning['text']}\n"
        
        # 特殊日期備注
        special_remark = ""
        special_occasion = self._check_special_date()
        if special_occasion:
            special_remark = f"\n?? {self.special_date_remarks[special_occasion]}"
        
        # 結束語
        closing = random.choice(self.closing_remarks)
        
        # 組合所有部分
        full_message = (
            f"{greeting}\n\n"
            f"{weather_summary}"
            f"{advice_section}"
            f"{forecast_section}"
            f"{warning_section}"
            f"{special_remark}\n\n"
            f"{closing}"
        )
        
        return full_message
    
    def generate_html_message(self, weather_data: Dict, advice_data: Dict,
                            forecast_data: List[Dict] = None) -> str:
        """生成HTML格式的消息(用于郵件)"""
        # 這里實現HTML格式的消息生成
        # 由于篇幅限制,具體實現略
        pass

4.4 消息發(fā)送模塊

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import logging
from typing import List

class MessageSender:
    """消息發(fā)送器,支持多種發(fā)送方式"""
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
    
    def send_email(self, recipient: str, subject: str, content: str,
                  smtp_host: str, smtp_port: int, 
                  username: str, password: str) -> bool:
        """通過郵件發(fā)送消息"""
        
        try:
            # 創(chuàng)建郵件對象
            msg = MIMEMultipart()
            msg['From'] = username
            msg['To'] = recipient
            msg['Subject'] = subject
            
            # 添加文本內容
            text_part = MIMEText(content, 'plain', 'utf-8')
            msg.attach(text_part)
            
            # 發(fā)送郵件
            with smtplib.SMTP(smtp_host, smtp_port) as server:
                server.starttls()  # 啟用TLS加密
                server.login(username, password)
                server.send_message(msg)
                
            self.logger.info(f"郵件發(fā)送成功:{recipient}")
            return True
            
        except Exception as e:
            self.logger.error(f"郵件發(fā)送失?。簕str(e)}")
            return False
    
    def send_wechat(self, content: str) -> bool:
        """通過微信發(fā)送消息(需要安裝itchat-uos)"""
        try:
            import itchat
            
            # 查找指定備注的好友
            friends = itchat.search_friends(name='女朋友的備注名')  # 修改為實際備注
            if friends:
                friend = friends[0]
                itchat.send(content, toUserName=friend['UserName'])
                self.logger.info("微信消息發(fā)送成功")
                return True
            else:
                self.logger.error("未找到指定的微信好友")
                return False
                
        except ImportError:
            self.logger.error("未安裝itchat-uos,無法發(fā)送微信消息")
            return False
        except Exception as e:
            self.logger.error(f"微信消息發(fā)送失?。簕str(e)}")
            return False
    
    def send_sms(self, phone_number: str, content: str, 
                api_key: str = None) -> bool:
        """通過短信API發(fā)送消息"""
        # 這里可以實現短信發(fā)送功能
        # 需要接入短信服務商API
        self.logger.info("短信發(fā)送功能需要接入短信服務商API")
        return False
    
    def send_multiple_ways(self, content: str, config: Dict) -> bool:
        """嘗試多種方式發(fā)送消息"""
        success = False
        
        # 嘗試郵件發(fā)送
        if config.get('email_enabled', False):
            success = self.send_email(
                recipient=config['recipient_email'],
                subject=config.get('email_subject', '每日天氣提醒'),
                content=content,
                smtp_host=config['smtp_host'],
                smtp_port=config['smtp_port'],
                username=config['email_username'],
                password=config['email_password']
            )
        
        # 如果郵件發(fā)送失敗,嘗試微信
        if not success and config.get('wechat_enabled', False):
            success = self.send_wechat(content)
            
        return success

5. 系統(tǒng)集成與完整實現

現在我們將所有模塊整合在一起,創(chuàng)建一個完整的天氣提醒系統(tǒng):

#!/usr/bin/env python3
"""
每日天氣提醒系統(tǒng)
為你的女朋友提供貼心的天氣提醒服務
日期:2024年1月
"""

import os
import logging
from datetime import datetime
from dotenv import load_dotenv
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
import sqlite3
from typing import Dict, Any

# 導入自定義模塊
from weather_service import WeatherService
from weather_analyzer import WeatherAnalyzer
from message_generator import MessageGenerator
from message_sender import MessageSender

# 加載環(huán)境變量
load_dotenv()

class DailyWeatherReminder:
    """每日天氣提醒系統(tǒng)主類"""
    
    def __init__(self, config: Dict[str, Any] = None):
        """初始化系統(tǒng)"""
        
        # 配置日志
        self._setup_logging()
        
        # 加載配置
        self.config = config or self._load_config()
        
        # 初始化組件
        self.weather_service = WeatherService(
            api_key=self.config['weather_api_key'],
            city=self.config['city']
        )
        self.weather_analyzer = WeatherAnalyzer()
        self.message_generator = MessageGenerator(
            recipient_name=self.config['recipient_name']
        )
        self.message_sender = MessageSender()
        
        # 初始化數據庫
        self._init_database()
        
        # 初始化調度器
        self.scheduler = BackgroundScheduler()
        
        self.logger.info("每日天氣提醒系統(tǒng)初始化完成")
    
    def _setup_logging(self):
        """配置日志系統(tǒng)"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('weather_reminder.log'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    
    def _load_config(self) -> Dict[str, Any]:
        """從環(huán)境變量加載配置"""
        return {
            'weather_api_key': os.getenv('WEATHER_API_KEY'),
            'city': os.getenv('WEATHER_CITY', '北京'),
            'smtp_host': os.getenv('EMAIL_HOST'),
            'smtp_port': int(os.getenv('EMAIL_PORT', 587)),
            'email_username': os.getenv('EMAIL_USER'),
            'email_password': os.getenv('EMAIL_PASSWORD'),
            'recipient_email': os.getenv('RECIPIENT_EMAIL'),
            'recipient_name': os.getenv('RECIPIENT_NAME', '親愛的'),
            'send_time': os.getenv('SEND_TIME', '07:30'),  # 默認早上7:30發(fā)送
            'email_enabled': True,
            'wechat_enabled': False
        }
    
    def _init_database(self):
        """初始化SQLite數據庫"""
        self.conn = sqlite3.connect('weather_reminder.db', check_same_thread=False)
        cursor = self.conn.cursor()
        
        # 創(chuàng)建發(fā)送記錄表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS send_history (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                send_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                success BOOLEAN,
                message TEXT,
                weather_data TEXT
            )
        ''')
        
        self.conn.commit()
    
    def _log_send_attempt(self, success: bool, message: str, weather_data: Dict):
        """記錄發(fā)送嘗試"""
        cursor = self.conn.cursor()
        cursor.execute(
            'INSERT INTO send_history (success, message, weather_data) VALUES (?, ?, ?)',
            (success, message, str(weather_data))
        )
        self.conn.commit()
    
    def get_weather_data(self) -> Dict[str, Any]:
        """獲取完整的天氣數據"""
        self.logger.info("開始獲取天氣數據...")
        
        weather_data = {}
        
        # 獲取當前天氣
        current_weather = self.weather_service.get_current_weather()
        if current_weather:
            weather_data.update(current_weather)
        else:
            self.logger.error("獲取當前天氣數據失敗")
            return {}
        
        # 獲取天氣預報
        forecast = self.weather_service.get_daily_forecast(days=3)
        if forecast:
            weather_data['forecast'] = forecast
        else:
            self.logger.warning("獲取天氣預報數據失敗")
        
        # 獲取天氣預警
        warnings = self.weather_service.get_weather_warning()
        if warnings:
            weather_data['warnings'] = warnings
        
        self.logger.info("天氣數據獲取完成")
        return weather_data
    
    def generate_weather_report(self) -> str:
        """生成完整的天氣報告"""
        try:
            # 獲取天氣數據
            weather_data = self.get_weather_data()
            if not weather_data:
                return "抱歉,今天無法獲取天氣信息。請手動查看天氣哦~"
            
            # 生成智能建議
            advice_data = self.weather_analyzer.generate_comprehensive_advice(weather_data)
            
            # 生成個性化消息
            forecast_data = weather_data.get('forecast', [])
            message = self.message_generator.generate_message(
                weather_data, advice_data, forecast_data
            )
            
            return message
            
        except Exception as e:
            self.logger.error(f"生成天氣報告時發(fā)生錯誤: {str(e)}")
            return f"今天天氣服務出了點小問題,但我的關心不會變~記得查看天氣哦!"
    
    def send_daily_reminder(self):
        """發(fā)送每日提醒(主函數)"""
        self.logger.info("開始發(fā)送每日天氣提醒...")
        
        try:
            # 生成天氣報告
            message = self.generate_weather_report()
            
            # 發(fā)送消息
            success = self.message_sender.send_multiple_ways(message, self.config)
            
            # 記錄發(fā)送結果
            weather_data = self.get_weather_data()  # 重新獲取用于記錄
            self._log_send_attempt(success, message, weather_data)
            
            if success:
                self.logger.info("每日天氣提醒發(fā)送成功")
            else:
                self.logger.error("所有發(fā)送方式均失敗")
                
            return success
            
        except Exception as e:
            self.logger.error(f"發(fā)送每日提醒時發(fā)生錯誤: {str(e)}")
            self._log_send_attempt(False, f"Error: {str(e)}", {})
            return False
    
    def setup_schedule(self):
        """設置定時任務"""
        # 解析發(fā)送時間
        hour, minute = map(int, self.config['send_time'].split(':'))
        
        # 添加每日定時任務
        self.scheduler.add_job(
            self.send_daily_reminder,
            trigger=CronTrigger(hour=hour, minute=minute),
            id='daily_weather_reminder',
            name='每日天氣提醒',
            replace_existing=True
        )
        
        self.logger.info(f"已設置每日 {hour:02d}:{minute:02d} 發(fā)送天氣提醒")
    
    def send_test_message(self):
        """發(fā)送測試消息"""
        self.logger.info("發(fā)送測試消息...")
        return self.send_daily_reminder()
    
    def start(self):
        """啟動系統(tǒng)"""
        try:
            # 設置定時任務
            self.setup_schedule()
            
            # 啟動調度器
            self.scheduler.start()
            
            self.logger.info("天氣提醒系統(tǒng)已啟動")
            
            # 立即發(fā)送一次測試消息
            self.send_test_message()
            
            # 保持程序運行
            try:
                while True:
                    # 主線程可以在這里執(zhí)行其他任務
                    # 或者簡單地等待
                    import time
                    time.sleep(60)
            except KeyboardInterrupt:
                self.logger.info("收到中斷信號,正在關閉系統(tǒng)...")
                
        except Exception as e:
            self.logger.error(f"啟動系統(tǒng)時發(fā)生錯誤: {str(e)}")
        finally:
            self.shutdown()
    
    def shutdown(self):
        """關閉系統(tǒng)"""
        if hasattr(self, 'scheduler') and self.scheduler.running:
            self.scheduler.shutdown()
        
        if hasattr(self, 'conn'):
            self.conn.close()
        
        self.logger.info("天氣提醒系統(tǒng)已關閉")


def main():
    """主函數"""
    
    # 可以在這里覆蓋默認配置
    custom_config = {
        'city': '上海',  # 修改為女朋友所在城市
        'send_time': '08:00',  # 修改為合適的發(fā)送時間
        # 添加其他自定義配置...
    }
    
    # 創(chuàng)建并啟動系統(tǒng)
    reminder_system = DailyWeatherReminder(custom_config)
    reminder_system.start()


if __name__ == "__main__":
    main()

6. 部署與運行

6.1 本地運行

創(chuàng)建項目目錄結構:

weather_reminder/
├── main.py
├── weather_service.py
├── weather_analyzer.py
├── message_generator.py
├── message_sender.py
├── .env
├── requirements.txt
└── config.json (可選)

安裝依賴:

pip install -r requirements.txt

配置環(huán)境變量(.env文件):

WEATHER_API_KEY=你的和風天氣API_KEY
WEATHER_CITY=北京
EMAIL_HOST=smtp.qq.com
EMAIL_PORT=587
EMAIL_USER=你的QQ郵箱
EMAIL_PASSWORD=QQ郵箱授權碼
RECIPIENT_EMAIL=女朋友的郵箱
RECIPIENT_NAME=親愛的
SEND_TIME=07:30

運行系統(tǒng):

python main.py

6.2 服務器部署

對于24小時運行,建議部署到云服務器:

使用systemd服務(Linux):創(chuàng)建/etc/systemd/system/weather-reminder.service

[Unit]
Description=Daily Weather Reminder
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/path/to/weather_reminder
ExecStart=/usr/bin/python3 main.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

使用Docker部署

創(chuàng)建Dockerfile:

FROM python:3.9-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

CMD ["python", "main.py"]

6.3 微信版本特別說明

如果要使用微信版本,需要注意:

安裝itchat-uos(解決微信網頁版登錄問題):

pip install itchat-uos

修改代碼使用微信發(fā)送:

# 在message_sender中啟用微信發(fā)送
def send_wechat_message(self, content: str) -> bool:
    import itchat
    
    # 自動登錄(會彈出二維碼)
    itchat.auto_login(hotReload=True, enableCmdQR=2)
    
    # 發(fā)送給文件傳輸助手(測試用)
    itchat.send(content, toUserName='filehelper')
    
    # 或者發(fā)送給指定好友
    friends = itchat.search_friends(name='女朋友的微信昵稱')
    if friends:
        itchat.send(content, toUserName=friends[0]['UserName'])
    
    itchat.logout()
    return True

7. 個性化定制建議

7.1 添加特殊日期提醒

MessageGenerator類中添加你們的特殊日期:

special_dates = {
    'anniversary': datetime(2024, 5, 20),  # 紀念日
    'birthday': datetime(2024, 8, 15),     # 生日
    'valentine': datetime(2024, 2, 14),    # 情人節(jié)
    'first_meet': datetime(2024, 3, 8)     # 初次見面日
}

7.2 自定義關懷語句

豐富問候語和結束語庫:

self.greetings = [
    "早安,我的小太陽{}!",
    "{}寶貝,新的一天開始啦",
    "嘿,{}!今天也是愛你的一天",
    "早上好,{}!你是我今天第一個想念的人"
]

self.closing_remarks = [
    "記得按時吃飯,你胃不好~",
    "今天也要想我一千遍哦",
    "工作再忙也要記得休息,心疼你",
    "晚上視頻哦,想你??"
]

7.3 天氣相關的情話

根據天氣添加不同的情話:

def get_weather_pickup_line(self, weather_text: str) -> str:
    """根據天氣生成情話"""
    lines = {
        '晴': "今天的陽光和你一樣溫暖我的心",
        '雨': "雨水可以打濕街道,但打不濕我想你的心",
        '云': "云朵遮住了太陽,但遮不住我對你的思念",
        '雪': "雪花飄落的時候,我在想你有沒有穿暖",
        '風': "風兒吹過,帶去我對你的牽掛"
    }
    
    for key, line in lines.items():
        if key in weather_text:
            return line
    return "無論什么天氣,你都是我的晴天"

8. 故障排除與優(yōu)化

8.1 常見問題解決

問題1:API調用失敗

  • 檢查API Key是否正確
  • 確認網絡連接正常
  • 查看天氣服務商的服務狀態(tài)

問題2:郵件發(fā)送失敗

  • 檢查郵箱授權碼(不是登錄密碼)
  • 確認SMTP服務器地址和端口正確
  • 檢查防火墻設置

問題3:定時任務不執(zhí)行

  • 確認系統(tǒng)時間正確
  • 檢查調度器是否正常啟動
  • 查看日志文件排查錯誤

8.2 性能優(yōu)化建議

緩存城市信息:避免重復查詢城市位置

錯誤重試機制:網絡請求失敗時自動重試

備用數據源:準備多個天氣API備用

消息隊列:使用Redis等管理發(fā)送任務

8.3 監(jiān)控與維護

  • 日志監(jiān)控:定期檢查系統(tǒng)日志
  • API使用量:監(jiān)控天氣API調用次數
  • 發(fā)送成功率:統(tǒng)計消息發(fā)送成功率
  • 定期備份:備份配置和發(fā)送記錄

9. 完整代碼文件

由于完整的代碼較長,這里提供各模塊的文件劃分:

9.1 requirements.txt

requests>=2.28.0
apscheduler>=3.9.0
python-dotenv>=0.19.0
python-dateutil>=2.8.0
itchat-uos>=1.5.0

9.2 weather_service.py

(包含WeatherService類,詳見第4.1節(jié))

9.3 weather_analyzer.py

(包含WeatherAnalyzer類,詳見第4.2節(jié))

9.4 message_generator.py

(包含MessageGenerator類,詳見第4.3節(jié))

9.5 message_sender.py

(包含MessageSender類,詳見第4.4節(jié))

9.6 main.py

(包含DailyWeatherReminder主類,詳見第5節(jié))

10. 總結

通過本文的指導,你已經學會了如何使用Python構建一個功能完整、貼心實用的每日天氣提醒系統(tǒng)。這個系統(tǒng)不僅技術上有價值,更重要的是它承載了你的情感和關懷。

10.1 技術收獲

  • 掌握了API調用的最佳實踐
  • 學會了構建模塊化的Python應用
  • 了解了定時任務的實現方式
  • 掌握了異常處理和日志記錄

10.2 情感價值

這個天氣提醒系統(tǒng)的真正價值在于:

  • 持續(xù)關懷:每天準時的提醒體現持續(xù)的關注
  • 個性化:根據天氣提供的建議展現細心和體貼
  • 實用性:真實的天氣信息幫助日常生活
  • 驚喜感:特殊日子的特別提醒增加浪漫氛圍

10.3 擴展思路

你可以進一步擴展這個系統(tǒng):

  • 添加更多消息平臺(釘釘、飛書等)
  • 集成日歷系統(tǒng),提醒重要日程
  • 添加機器學習,學習女朋友的偏好
  • 開發(fā)手機APP,提供更好的交互體驗

記住,技術只是工具,真正打動人心的永遠是你的用心和關懷。希望這個天氣提醒系統(tǒng)能為你們的感情增添一份科技的溫暖!

溫馨提示:在使用過程中,請尊重女朋友的隱私和偏好,確保她喜歡這樣的關懷方式。技術應該服務于感情,而不是替代真實的交流和相處。祝你們的感情像精心編寫的代碼一樣,穩(wěn)定而美好!

以上就是使用Python編寫一個每日天氣提醒的詳細內容,更多關于Python每日天氣提醒的資料請關注腳本之家其它相關文章!

相關文章

  • pytorch 兩個GPU同時訓練的解決方案

    pytorch 兩個GPU同時訓練的解決方案

    這篇文章主要介紹了pytorch 兩個GPU同時訓練的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Numpy?np.array()函數使用方法指南

    Numpy?np.array()函數使用方法指南

    numpy是一個在Python中做科學計算的基礎庫,重在數值計算,也是大部分Python科學計算庫的基礎庫,多用于大型、多維數據上執(zhí)行數值計算,下面這篇文章主要給大家介紹了關于Numpy?np.array()函數使用方法指南的相關資料,需要的朋友可以參考下
    2022-12-12
  • Python將圖片轉換為字符畫的方法

    Python將圖片轉換為字符畫的方法

    這篇文章主要為大家詳細介紹了Python將圖片轉換為字符畫的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • 如何使用repr調試python程序

    如何使用repr調試python程序

    這篇文章主要介紹了如何使用repr調試python程序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Python利用FFmpeg處理音視頻的詳細教程

    Python利用FFmpeg處理音視頻的詳細教程

    FFmpeg是一個功能強大的開源多媒體處理工具,能夠處理幾乎所有類型的音頻和視頻文件,在Python中,通過ffmpeg-python庫,我們可以輕松地在Python腳本中調用FFmpeg的功能,本教程將詳細介紹如何在Python中使用ffmpeg-python庫,并通過實際案例展示其用法,需要的朋友可以參考下
    2024-08-08
  • Python使用Websocket推送數據實例

    Python使用Websocket推送數據實例

    WebSocket是一種在單個TCP連接上進行全雙工通信的協(xié)議,上述HTML和Python文件可能用于建立WebSocket服務器,實現客戶端與服務器之間的實時通信
    2023-05-05
  • 新手必備Python開發(fā)環(huán)境搭建教程

    新手必備Python開發(fā)環(huán)境搭建教程

    今天向大家介紹如何搭建Python開發(fā)環(huán)境, Python可應用于多平臺包括 Linux 和 Mac OS X,文中有非常詳細的圖文介紹,需要的朋友可以參考下
    2021-05-05
  • Python劃分數組為連續(xù)數字集合的練習

    Python劃分數組為連續(xù)數字集合的練習

    這篇文章主要給大家分享的是Python劃分數組為連續(xù)數字集合的練習,下面文章首先對問題進行詳細描述,在根據問題提出解決方案,內容詳細,需要的朋友可以參考一下,希望對你有所幫助
    2021-11-11
  • 如何卸載python插件

    如何卸載python插件

    在本篇文章里小編給大家分享了關于python插件如何卸載的相關文章,需要的朋友們可以參考下。
    2020-07-07
  • 使用uv管理python虛擬環(huán)境的流程步驟

    使用uv管理python虛擬環(huán)境的流程步驟

    uv是高效Python虛擬環(huán)境管理工具,支持多平臺,可替代pip等,提升性能10倍以上,管理版本與依賴,集成MCP協(xié)議,簡化開發(fā)流程,本文給大家詳細介紹了如何使用uv管理python虛擬環(huán)境的流程步驟,需要的朋友可以參考下
    2025-06-06

最新評論

卢氏县| 岳阳市| 大新县| 英吉沙县| 平昌县| 南昌市| 阳新县| 平利县| 微博| 合肥市| 锡林郭勒盟| 繁峙县| 德江县| 青阳县| 老河口市| 云林县| 东安县| 威宁| 内黄县| 抚顺市| 文成县| 大荔县| 昌乐县| 浦县| 鹿泉市| 玉田县| 襄樊市| 丹凤县| 斗六市| 田东县| 景德镇市| 江津市| 前郭尔| 淮安市| 巴楚县| 曲沃县| 白河县| 岢岚县| 察隅县| 象州县| 张掖市|