定时发送免费天气预报(邮件)短信通知的Python脚本,通用Linux,也适合树莓派

最近在摆弄Python和树莓派,故写了个定时发送免费天气预报(邮件)短信通知的Python脚本,通用Linux,也适合树莓派或者Windows系统,为Python3版本,Python2环境下使用的话,则要重新载入sys并设置utf8。

这里提供的是个人使用的单用户单城市版本。

# -*- coding: utf-8 -*-
"""
Spyder Editor
一个适合个人使用的定时发送天气预报短信的Python脚本.
原理,自动发送到你自己的邮箱,然后若邮箱有短信通知功能,就等于实现了短信通知。
一般运营商的邮箱都有这个邮件到达短信通知功能。
若改一改,就可以实现批量群发和多城市查询,甚至可以实现自动发送微信版天气预报通知到指定手机。
可放在树莓派中设置为开机自动运行。
树莓派中使用时,请用python3 XXX.py 方式启动。因为树莓派中python默认是python2。
需自己配置的参数有5个,请自行修改下方程序中对应项目:
fzs='18:18:00'                 设置邮件发送的时间,样例中是每天的18点18分发送天气预报邮件
Get_weather_data('北京')  修改对应的城市名称为你需要查询的城市
'your_fs_mail@163.com'   应修改为发送邮件的邮箱,样例中是163邮箱
'your_sq_mail@139.com'   应修改为收取天气预报邮件的邮箱,样例中是139邮箱
"your_mima"              应修改为发送邮件的邮箱对应的发送邮件密码,一般的邮箱同登录密码,但网易163系列邮箱则是授权码,不是登录密码
部分代码实现参考了网络上其他作者的代码,本程序已经调试通过,无bug
修正日志:
20200625,因为数据源对风力的解析结果稍有变化,现配对为最新的风力解析方式
"""

#导入必要模块
import requests
import json
import datetime
import time
import sys
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

#定时任务
def timerFun(sched_Timer):
    flag=0
    while True:
        now=datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
        xcsj=sched_Timer.strftime('%Y-%m-%d %H:%M')
        if now==xcsj:
            flag=1
            #执行天气预报查询并发送邮件
            print('时间一致,开始发送天气预报邮件')
            weather_data = Get_weather_data('北京')
            weather_forecast_txt, forecast, nr = Show_weather(weather_data)
            if weather_forecast_txt=='N':
                print('查询天气的地址不对,程序终止')
                sys.exit()
            to_email(weather_forecast_txt,nr)
        else:
            if flag==1:
                sched_Timer=sched_Timer+datetime.timedelta(days=1)#days=1按天循环,minutes=1按分钟循环,hours=1按小时循环
                print('下次比较时间是:'+sched_Timer.strftime('%Y-%m-%d %H:%M'))
                flag=0
        time.sleep(60)#每60秒检查一次即可

#定义获取天气数据函数
def Get_weather_data(diqu):
    print('------天气查询------')
    city_name=diqu
    url = 'http://wthrcdn.etouch.cn/weather_mini?city=' + city_name
    while True:
        res=requests.get(url)
        try:
            res.raise_for_status()
            res.encoding = res.apparent_encoding  #设置编码
            weather_data=res.text
            break
        except Exception as exc:
            print('产生一个故障: %s%s,120秒后重试' % (url,'打开失败'))
            time.sleep(120)
    # 读取网页数据
    weather_dict = json.loads(weather_data)
    return weather_dict
#定义当天天气输出格式
def Show_weather(weather_data):
    weather_dict = weather_data
    if weather_dict.get('desc') == 'invilad-citykey':
        print('你输入的城市有误或未收录天气,请重新输入...')
        weather_forecast_txt='N'
        forecast='N'
        nr='N'
    elif weather_dict.get('desc') == 'OK':
        forecast = weather_dict.get('data').get('forecast')# 算星期几
        print('日期:%s' % forecast[1].get('date'))
        print('城市:%s' % weather_dict.get('data').get('city'))
        print('天气:%s' % forecast[1].get('type'))
        print('温度:%s' % (weather_dict.get('data').get('wendu') + ''))
        print('高温:%s' % forecast[1].get('high'))
        print('低温:%s' % forecast[1].get('low'))
        print('风级:%s' % forecast[1].get('fengli').split('[')[2].split(']')[0])
        print('风向:%s' % forecast[1].get('fengxiang'))
        weather_forecast_txt = '%s,%s,' \
                               '%s,' \
                               '%s-' \
                               '%s,' \
                               '风力%s,' \
                               '当前温度%s,%s天气预报' % \
                               (
                                   weather_dict.get('data').get('city'),
                                   str((datetime.date.today()+datetime.timedelta(days=1))).replace('-',''),
                                   forecast[1].get('type'),
                                   str(forecast[1].get('low')).replace('低温',''),
                                   forecast[1].get('high').replace('高温',''),                                   
                                   forecast[1].get('fengli').split('[')[2].split(']')[0],
                                   weather_dict.get('data').get('wendu') + '',
                                   weather_dict.get('data').get('city')
                               )
        nr='温馨提示:%s   发送时间:%s' % (weather_dict.get('data').get('ganmao'),datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    return weather_forecast_txt,forecast,nr
#发送邮件
def to_email(bt,nr):
    my_sender='your_fs_mail@163.com' #设置发件人邮箱账号,为了后面易于维护,所以写成了变量
    my_user='your_sq_mail@139.com' #收件人邮箱账号,为了后面易于维护,所以写成了变量,写成运营商的邮箱可以利用邮件到达通知功能实现天气预报短信功能。
    def mail():
        ret=True
        try:
            msg=MIMEText(nr,'plain','utf-8')
            msg['From']=formataddr(["天气预报",my_sender])   #括号里的对应发件人邮箱昵称、发件人邮箱账号
            msg['To']=formataddr(["H",my_user])   #括号里的对应收件人邮箱昵称、收件人邮箱账号
            msg['Subject']=bt #邮件的主题,也可以说是标题
            server=smtplib.SMTP("smtp.163.com",25)  #发件人邮箱中的SMTP服务器,端口是25
            server.login(my_sender,"your_mima")    #设置163邮箱的smtp授权码,不是163邮箱登录密码。括号中对应的是发件人邮箱账号、邮箱密码
            server.sendmail(my_sender,[my_user,],msg.as_string())   #括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
            server.quit()   #这句是关闭连接的意思
        except Exception:   #如果try中的语句没有执行,则会执行下面的ret=False
            ret=False
        return ret
    bccs=20#设置报错尝试的次数
    js=0#初始化报错计数
    while True:
        ret=mail()
        if ret:
            print("邮件发送成功!标题:%s,内容:%s" % (bt,nr)) #如果发送成功则会返回ok,稍等20秒左右就可以收到邮件
            break
        else:
            print("邮件发送失败!30秒后重试")  #如果发送失败则会返回filed
            js=js+1
            if js<=bccs:
                time.sleep(30)
            else:
                break
#主函数
if __name__=='__main__':
    #开机预留启动时间,方便树莓派联网
    time.sleep(10)
    today = datetime.date.today()
    tomorrow = today + datetime.timedelta(days=1)
    jtrq=today.strftime('%Y-%m-%d')
    fzs='18:18:00'#设置邮件发送的时间
    jtrq=jtrq+' '+fzs#设置小时分秒,以后每天这个时候会发送,精确到分钟
    if datetime.datetime.strptime(jtrq,'%Y-%m-%d %H:%M:%S')>datetime.datetime.now():
        sched_Timer=datetime.datetime.strptime(jtrq,'%Y-%m-%d %H:%M:%S')
    else:
        sched_Timer=datetime.datetime.strptime(tomorrow.strftime('%Y-%m-%d')+' '+fzs,'%Y-%m-%d %H:%M:%S')
    qdbt='天气预报启动成功,时间:%s' % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    qdnr='第一次发送时间为:%s' % sched_Timer
    to_email(qdbt,qdnr)
    time.sleep(5)
    timerFun(sched_Timer)#按天循环

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要现定时运行 Python 脚本发送邮件,可以使用 Python 的第三方库 schedule 和 smtplib。 首先,安装这两个库: ```python pip install schedule ``` ```python pip install secure-smtplib ``` 接下来,编写 Python 脚本,实现定时发送邮件的功能: ```python import schedule import time import smtplib from email.mime.text import MIMEText from email.header import Header # 定义发送邮件的函数 def send_email(): # 邮件内容 mail_content = '这是一封测试邮件' # 发送信息 sender = '发送方邮箱' password = '发送方邮箱密码' # 接收方信息 receivers = ['接收方邮箱'] # 邮件标题和内容 message = MIMEText(mail_content, 'plain', 'utf-8') message['From'] = Header(sender) message['To'] = Header(','.join(receivers)) message['Subject'] = Header('测试邮件') # 发送邮件 try: smtp_obj = smtplib.SMTP_SSL('smtp.qq.com', 465) smtp_obj.login(sender, password) smtp_obj.sendmail(sender, receivers, message.as_string()) print('邮件发送成功') except smtplib.SMTPException as e: print('邮件发送失败', e) # 定义定时任务 def job(): print('开始发送邮件...') send_email() # 设置定时任务,每隔一定时间执行一次 schedule.every(10).minutes.do(job) # 每隔10分钟执行一次 # schedule.every().hour.do(job) # 每小时执行一次 # schedule.every().day.at('10:30').do(job) # 每天10:30执行一次 # 循环执行定时任务 while True: schedule.run_pending() time.sleep(1) ``` 在上述代码中,`send_email()` 函数定义了如何发送邮件,而 `job()` 函数则定义了定时任务的具体内容。在这里,我们将每隔10分钟执行一次 `job()` 函数,可以根据自己的需要设置定时任务的时间间隔。 最后,在命令行中运行该 Python 脚本即可。注意,为了保证邮件能够正常发送,需要在发送方邮箱的设置中开启 SMTP 服务,并且在代码中填写正确的发送方邮箱和密码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值