基于Python的本地天气提醒工具开发实践



背景介绍

在日常生活中,天气变化对我们的出行和工作安排有着重要影响。尤其在雨天,是否需要带伞、是否需要调整衣着,都取决于天气预报的准确性。对于开发者而言,构建一个本地天气提醒工具,不仅可以帮助自己或他人及时掌握天气信息,还能作为学习Python中网络请求、定时任务、邮件发送、配置管理等技术点的实战项目。

本文将详细介绍如何使用Python开发一个定时查询天气并通过邮件提醒用户的小工具。该工具具备良好的可配置性,用户只需修改一个配置文件即可自定义城市、提醒时间、提醒方式等。


思路分析

本项目的主要功能模块如下:

  1. 读取配置文件:从JSON文件中加载用户设置,包括城市、提醒时间、提醒方式、邮箱信息等。
  2. 调用天气API:使用第三方天气API(如和风天气)获取指定城市的天气信息。
  3. 定时任务:使用 schedule 库设置定时任务,每天在指定时间执行天气查询和提醒逻辑。
  4. 发送提醒
    • 如果选择邮件提醒,使用 smtplib 发送邮件;
    • 如果选择系统通知,使用 plyer 库发送桌面通知。
  5. 条件判断:根据天气数据(如是否下雨、温度变化)生成提醒内容。

代码实现

1. 安装依赖库

在开始之前,请确保已安装以下Python库:

pip install requests schedule plyer

2. 配置文件 config.json

{
    "city": "上海",
    "reminder_time": "08:00",
    "notification_type": "email",
    "email": {
        "sender": "your_email@163.com",
        "password": "your_smtp_password",
        "receiver": "user@example.com",
        "smtp_server": "smtp.163.com",
        "smtp_port": 465
    }
}

3. 天气API调用模块 weather_api.py

import requests

def get_weather(city, api_key="YOUR_API_KEY"):
    """
    从和风天气API获取天气信息
    :param city: 城市名
    :param api_key: 和风天气API密钥
    :return: 天气描述(如:多云,22°C,有雨)
    """
    url = f"https://devapi.qweather.com/v7/weather/24h?location={city}&key={api_key}"
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        if data["code"] == "200":
            weather = data["hourly"][0]  # 获取当前天气
            description = weather["text"]
            temp = weather["temp"]
            is_raining = "雨" in description
            return f"{description},{temp}°C,{'有雨' if is_raining else '无雨'}"
    return "天气信息获取失败"

注意:你需要注册 和风天气 获取API密钥,并替换 YOUR_API_KEY


4. 邮件发送模块 email_notifier.py

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import datetime

def send_email(subject, content, config):
    """
    发送邮件提醒
    :param subject: 邮件主题
    :param content: 邮件内容
    :param config: 邮件配置字典
    """
    sender_email = config["email"]["sender"]
    sender_password = config["email"]["password"]
    receiver_email = config["email"]["receiver"]
    smtp_server = config["email"]["smtp_server"]
    smtp_port = config["email"]["smtp_port"]

    msg = MIMEMultipart()
    msg["Subject"] = f"{subject} - {datetime.datetime.now().strftime('%Y-%m-%d')}"
    msg["From"] = sender_email
    msg["To"] = receiver_email

    body = f"""
    <h3 style="text-align:center;">{subject}</h3>
    <p>{content}</p>
    """
    msg.attach(MIMEText(body, "html"))

    try:
        with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
            server.login(sender_email, sender_password)
            server.sendmail(sender_email, receiver_email, msg.as_string())
        print("邮件发送成功!")
    except Exception as e:
        print(f"邮件发送失败: {e}")

5. 系统通知模块 notification_notifier.py

from plyer import notification
import datetime

def send_notification(title, message):
    """
    发送系统桌面通知
    :param title: 通知标题
    :param message: 通知内容
    """
    notification.notify(
        title=title,
        message=message,
        timeout=10
    )
    print("系统通知已发送。")

6. 主程序 weather_reminder.py

import json
import time
import schedule
from weather_api import get_weather
from email_notifier import send_email
from notification_notifier import send_notification

def load_config():
    """加载配置文件"""
    with open("config.json", "r", encoding="utf-8") as f:
        return json.load(f)

def check_weather_and_notify(config):
    city = config["city"]
    weather_info = get_weather(city)
    print(f"获取到天气信息:{weather_info}")

    if "有雨" in weather_info:
        reminder_content = f"今日{city}天气:{weather_info}。建议携带雨具出门。"
    else:
        reminder_content = f"今日{city}天气:{weather_info}。天气良好,注意保暖。"

    if config["notification_type"] == "email":
        send_email("天气提醒", reminder_content, config)
    elif config["notification_type"] == "notification":
        send_notification("天气提醒", reminder_content)

def main():
    config = load_config()
    schedule.every().day.at(config["reminder_time"]).do(check_weather_and_notify, config)

    print(f"天气提醒工具已启动,将在每天 {config['reminder_time']} 查询 {config['city']} 天气。")
    while True:
        schedule.run_pending()
        time.sleep(1)

if __name__ == "__main__":
    main()

总结

本项目通过Python实现了定时查询天气并根据天气情况发送提醒的功能,涵盖了以下核心技术点:

  • 网络请求:使用 requests 调用和风天气API;
  • 定时任务:使用 schedule 设置每天固定时间执行;
  • 邮件发送:使用 smtplibemail 模块发送HTML格式邮件;
  • 配置管理:使用JSON文件存储用户配置;
  • 系统通知:使用 plyer 库发送桌面通知;
  • 条件判断:根据天气信息生成不同的提醒内容。

该项目结构清晰、模块化良好,适合初学者练习Python在自动化任务中的应用。通过本项目,你可以掌握如何将多个Python模块组合使用,构建一个实用的小工具。


附加建议

  • 你可以扩展为支持多城市提醒;
  • 可以添加日志记录功能,记录每次查询和提醒结果;
  • 可以使用GUI框架(如Tkinter)为工具添加图形界面;
  • 可以部署为Windows服务或Linux后台进程,实现长期运行。

希望这篇文章能帮助你更好地理解和实践Python自动化开发!


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注