一、前言
閒暇之餘,想給身邊的朋友每天定時發送問候,本來想調微信來實現的,但由於微信處於安全考慮,已將網頁授權登錄關閉;
所以就想着用郵箱代替來實現一個每日關愛腳本 !!!
下面我們先看一下效果,如圖;
好文章 記得收藏+點贊+關注額 !!!---- 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 = ' ' \ ' ' # 填充每日一句模板 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 = ' ' \ ' ' # 填充每日一句模板 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("========== 每日華麗分割線 ==========")