Python + Email每天定時自動給女朋友發送天氣預報等各種關愛

一、前言

閒暇之餘,想給身邊的朋友每天定時發送問候,本來想調微信來實現的,但由於微信處於安全考慮,已將網頁授權登錄關閉;

所以就想着用郵箱代替來實現一個每日關愛腳本 !!!

下面我們先看一下效果,如圖;

好文章 記得收藏+點贊+關注額 !!!

---- Nick.Peng


二、關愛郵件效果圖

  • 大概郵件信息以及格式如下,大家可以根據各自的需求微調;
    在這裏插入圖片描述

三、發送關愛郵件實現步驟

3.1、獲取天氣方法

  • 定義一個每日關愛郵件類;

  • 定義實例屬性,下面會用到;

  • 定義獲取天氣信息的方法,詳情如下,每個步驟都有備註,很容易懂;

    • 調用實例屬性天氣API;
    • 提取周信息、天氣狀況、最低最高氣溫、風向、風力、感冒預警關愛信息;
    • 制定郵件天氣模版並填充以上提取的信息;
    class DailyGreeting(object):
    	"""
        每日郵件關愛
        """
        def __init__(self):
            self.cb_link = 'http://open.iciba.com/dsapi/'                       # 金山詞霸api提供的每日一句
            self.whether_link = 'http://wthrcdn.etouch.cn/weather_mini?city='   # 天氣api
    
        def get_whether(self, city):
            """
            獲取天氣信息
            :param city: 城市
            :return: msg
            """
            url = self.whether_link + city
            r = requests.get(url).json()
            week = r['data']['forecast'][0]['date'][-3:]            # 周幾
            weather = r['data']['forecast'][0]['type']              # 天氣
            low_temp = r['data']['forecast'][0]['low'][3:]          # 最低氣溫
            high_temp = r['data']['forecast'][0]['high'][3:]        # 最高氣溫
            wind_dir = r['data']['forecast'][0]['fengxiang']        # 風向
            wind_force = r['data']['forecast'][0]['fengli'][9:-3]   # 風力
            warn = r['data']['ganmao']                              # 感冒預提醒
            # 填充天氣信息模板
            msg = '<br>親愛的朋友,' + '今天 ' + week + '<br>' + \
                  '<br><font size=3 color=#0081ff><strong>天氣:</strong></font>' + city + ' ' + weather + \
                  '<br><font size=3 color=#0081ff><strong>溫度:</strong></font>' + low_temp + '~' + high_temp + \
                  '<br><font size=3 color=#0081ff><strong>風向:</strong></font>' + wind_dir + ',' + wind_force + \
                  '<br><br><font size=3 color=red><strong>注意:</strong></font>' + warn + '<br>'
            return str(msg)
    

3.2、獲取詞霸每日一句方法

  • 定義get_word方法,並調用實例屬性詞霸每日一句API;

  • 提取中英文每日一句;

  • 制定郵件每日一句模版並填充以上提取的信息;

    def get_word(self):
        """
        獲取金山詞霸每日一句
        :return: msg
        """
        r = requests.get(self.cb_link).json()
        en = r['content']
        cn = r['note']
        indent = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' \
                 '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
        # 填充每日一句模板
        msg = '<br><font size=3 color=lightpink><strong><i>' + en + '<br>' + cn + '</strong></font><br>' + \
              '<br>' + indent + '<font size=3 color=#a5673f>—— 最關心你的人兒~' + \
              '<br><html><body><img src={}></body></html>'.format(r['fenxiang_img'])
        return str(msg)
    

3.3、發送郵件方法

  • 指定發件人郵件地址和登錄授權碼;

  • 創建一個郵件對象,並指定郵件主題,發件人,收件人等;

  • 創建郵件客戶端對象,連接郵箱服務器地址,登錄認證,並調用sendmail發送郵件,發送完畢斷開郵箱服務連接;

    @staticmethod
    def send_email_message(email, message):
        """
        完成發送郵件功能
        :param email: 收件人
        :param message: 郵件發送內容
        :return:
        """
        # 發件人郵箱地址
        sender = '[email protected]'
        # 客戶端授權碼:需要在註冊郵箱後,登錄進入->設置->常規設置->客戶端授權碼 裏面進行設置
        auth_code = 'SISQXKZBXVBDADASD'
        messageObj = MIMEText(message, "html", "utf-8")
        # 設置主題
        messageObj['Subject'] = Header("每日溫馨提醒!", "utf-8")
        # 設置發件人
        messageObj['From'] = sender
        # 設置收件人
        messageObj['To'] = email
        try:
            # 建立客戶端
            smtpObj = smtplib.SMTP()
            # 連接163郵箱服務器地址
            smtpObj.connect('smtp.163.com')
            # 方法二:利用SSL的方式發送
            # smtpObj = smtplib.SMTP_SSL('smtp.163.com', 465)
            # smtpObj.ehlo()    # 使用EHLO向ESMTP服務器標識自己
            # 登錄認證
            smtpObj.login(sender, auth_code)
            # 發送郵件
            smtpObj.sendmail(sender, [email], messageObj.as_string())
            # 斷開連接
            smtpObj.close()
            print("Send mail successfully.")
            return True
        except smtplib.SMTPException as e:
            print("Send email failed.")
            print("Error logs: ", e)
            return False
    

3.4、調度方法實現

  • 對調用傳遞的好友練習方式進行遍歷,並調用send_email_message分別發送郵件;

    def main(self, friend_list):
        """
        調度方法
        :return: Boole
        """
        for friend in friend_list:
            mail = friend.get('mail')
            city = friend.get('city')
            cur_whether = self.get_whether(city)
            cur_word = self.get_word()
            # 構造郵件的正文內容
            msg = '您的貼心小祕上線啦 !!!<br>' + cur_whether + cur_word
            print("=========={}: {}".format(friend.get('mail'), msg))
            self.send_email_message(mail, msg)
    

3.5、定時任務實現

  • 自定義定時任務如下,詳見註釋;

    SECONDS_PER_DAY = 24 * 60 * 60  # 一天時間(秒)
    SET_TIME = 7                    # 定時每日7點執行一次
    is_first = True                 # 是否第一次執行任務
    now = datetime.datetime.now()   # 第一次執行獲取當前時間
    # 定時執行任務邏輯
    while True:
        cur_s = now.hour * 60 * 60 + now.minute * 60 + now.second   # 當前時間(時+分+秒)--> 秒
        first_gap_s = 0     # 第一次等待的時間(秒)
        if now.hour > SET_TIME:
            # 當前時間小時數 大於 7點
            first_gap_s = 24 * 60 * 60 - cur_s + SET_TIME * 60 * 60 # 差距 --> 秒
        elif now.hour < SET_TIME:
            # 當前時間小時數 小於 7點
            first_gap_s = SET_TIME * 60 * 60 - cur_s
        if is_first:
            # 第一次執行需要等待的時間,即first_gap_s秒後調用main()發送郵件
            time.sleep(first_gap_s)
        else:
            time.sleep(SECONDS_PER_DAY)     # 每24H執行一次
        DailyGreeting().main(friend_list)
        is_first = False    # 第一次執行完後將is_first置False
    

四、完整源代碼

  • 同學們期待的完整源碼來啦 !!!趕緊擼下來吧。^o^ ~ ^o^

  • 有了它,我們就可以將其上傳到服務器,使用以下命令運行即可實現每日給親朋好友發送郵件啦;

  • 命令: nohup python3 Send_greeting.py >message.out 2>&1 &

  • 在這裏順便 送大家 一套2020最有趣的Pyhon項目實戰視頻教程視頻地址: 點擊進去就能免費拿,希望大家一起進步!

    # -*- coding: utf-8 -*-
    # @Author: Nick
    # @Last Modified by:   Nick
    # @Last Modified time: 2020-03-31 16:21:36
    
    import time
    import datetime
    import requests
    import smtplib
    from email.mime.text import MIMEText
    from email.header import Header
    
    
    class DailyGreeting(object):
        """
        每日郵件關愛
        """
        def __init__(self, friend_list):
            self.cb_link = 'http://open.iciba.com/dsapi/'                       # 金山詞霸api提供的每日一句
            self.whether_link = 'http://wthrcdn.etouch.cn/weather_mini?city='   # 天氣api
            self.friend_list = friend_list
    
        def get_whether(self, city):
            """
            獲取天氣信息
            :param city: 城市
            :return: msg
            """
            url = self.whether_link + city
            r = requests.get(url).json()
            week = r['data']['forecast'][0]['date'][-3:]            # 周幾
            weather = r['data']['forecast'][0]['type']              # 天氣
            low_temp = r['data']['forecast'][0]['low'][3:]          # 最低氣溫
            high_temp = r['data']['forecast'][0]['high'][3:]        # 最高氣溫
            wind_dir = r['data']['forecast'][0]['fengxiang']        # 風向
            wind_force = r['data']['forecast'][0]['fengli'][9:-3]   # 風力
            warn = r['data']['ganmao']                              # 感冒預提醒
            # 填充天氣信息模板
            msg = '<br>親愛的朋友,' + '今天 ' + week + '<br>' + \
                  '<br><font size=3 color=#0081ff><strong>天氣:</strong></font>' + city + ' ' + weather + \
                  '<br><font size=3 color=#0081ff><strong>溫度:</strong></font>' + low_temp + '~' + high_temp + \
                  '<br><font size=3 color=#0081ff><strong>風向:</strong></font>' + wind_dir + ',' + wind_force + \
                  '<br><br><font size=3 color=red><strong>注意:</strong></font>' + warn + '<br>'
            return str(msg)
    
        def get_word(self):
            """
            獲取金山詞霸每日一句
            :return: msg
            """
            r = requests.get(self.cb_link).json()
            en = r['content']
            cn = r['note']
            indent = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' \
                     '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
            # 填充每日一句模板
            msg = '<br><font size=3 color=lightpink><strong><i>' + en + '<br>' + cn + '</strong></font><br>' + \
                  '<br>' + indent + '<font size=3 color=#a5673f>—— 最關心你的人兒~' + \
                  '<br><html><body><img src={}></body></html>'.format(r['fenxiang_img'])
            return str(msg)
    
        @staticmethod
        def send_email_message(email, message):
            """
            完成發送郵件功能
            :param email: 收件人
            :param message: 郵件發送內容
            :return:
            """
            # 發件人郵箱地址
            sender = '[email protected]'
            # 客戶端授權碼:需要在註冊郵箱後,登錄進入->設置->常規設置->客戶端授權碼 裏面進行設置
            auth_code = 'SISQXKZBXVBDADASD'
            messageObj = MIMEText(message, "html", "utf-8")
            # 設置主題
            messageObj['Subject'] = Header("每日溫馨提醒!", "utf-8")
            # 設置發件人
            messageObj['From'] = sender
            # 設置收件人
            messageObj['To'] = email
            try:
                # 建立客戶端
                smtpObj = smtplib.SMTP()
                # 連接163郵箱服務器地址
                smtpObj.connect('smtp.163.com')
                # 方法二:利用SSL的方式發送
                # smtpObj = smtplib.SMTP_SSL('smtp.163.com', 465)
                # smtpObj.ehlo()    # 使用EHLO向ESMTP服務器標識自己
                # 登錄認證
                smtpObj.login(sender, auth_code)
                # 發送郵件
                smtpObj.sendmail(sender, [email], messageObj.as_string())
                # 斷開連接
                smtpObj.close()
                print("Send mail successfully.")
                return True
            except smtplib.SMTPException as e:
                print("Send email failed.")
                print("Error logs: ", e)
                return False
    
        def main(self):
            """
            調度方法
            :return: Boole
            """
            for friend in self.friend_list:
                mail = friend.get('mail')
                city = friend.get('city')
                cur_whether = self.get_whether(city)
                cur_word = self.get_word()
                # 構造郵件的正文內容
                msg = '您的貼心小祕上線啦 !!!<br>' + cur_whether + cur_word
                print("=========={}: {}".format(friend.get('mail'), msg))
                self.send_email_message(mail, msg)
    
    
    if __name__ == '__main__':
        # 需要發送郵件的聯繫方式
        friend_list = [{'mail': '[email protected]', 'city': '鄭州'}]
        # DailyGreeting(friend_list).main()
    
        SECONDS_PER_DAY = 24 * 60 * 60  # 一天時間(秒)
        SET_TIME = 7                    # 定時每日7點執行一次
        is_first = True                 # 是否第一次執行任務
        now = datetime.datetime.now()   # 第一次執行獲取當前時間
        # 定時執行任務邏輯
        while True:
            cur_s = now.hour * 60 * 60 + now.minute * 60 + now.second   # 當前時間(時+分+秒)--> 秒
            first_gap_s = 0     # 第一次等待的時間(秒)
            if now.hour > SET_TIME:
                # 當前時間小時數 大於 7點
                first_gap_s = 24 * 60 * 60 - cur_s + SET_TIME * 60 * 60 # 差距 --> 秒
                print("========== 大於時 ==========", first_gap_s)
            elif now.hour < SET_TIME:
                # 當前時間小時數 小於 7點
                first_gap_s = SET_TIME * 60 * 60 - cur_s
                print("========== 小於時 ==========", first_gap_s)
            if is_first:
                # 第一次執行需要等待的時間,即first_gap_s秒後調用main()發送郵件
                time.sleep(first_gap_s)
            else:
                print("========== 24H 之後再次執行 ==========")
                time.sleep(SECONDS_PER_DAY)     # 每24H執行一次
            DailyGreeting(friend_list).main()
            is_first = False    # 第一次執行完後將is_first置False
            print("========== 每日華麗分割線 ==========")
    
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章