python-發送郵件與定時


python-發送郵件與定時

1.發送郵件

先來模仿一下平時我們發郵件時計算機的操作

我們的代碼邏輯也會按照上圖來進行,並且在其中用到兩個庫——smtplibemail

以qq郵箱為例,先來看第0步:連接服務器。

連接服務器需要用到smtplib庫。為什么叫這個名字呢?其實,SMTP代表簡單郵件傳輸協議,相當於一種計算機之間發郵件的約定。

好,來看下具體怎么用smtplib庫來連接服務器:

import smtplib 
#smtplib是python的一個內置庫,所以不需要用pip安裝
mailhost='smtp.qq.com'
#把qq郵箱的服務器地址賦值到變量mailhost上,地址需要是字符串的格式。
qqmail = smtplib.SMTP()
#實例化一個smtplib模塊里的SMTP類的對象,這樣就可以SMTP對象的方法和屬性了
qqmail.connect(mailhost,25)
#連接服務器,第一個參數是服務器地址,第二個參數是SMTP端口號。

解釋一下:第1行代碼是引入庫,第2行代碼是qq郵箱的服務器地址,這個地址是可以通過搜索引擎查到的。

第7行代碼是用SMTP對象的connect()方法連接服務器,第一個參數是獲取到的服務器地址,第二個參數是SMTP端口號——25

端口號的選擇不是唯一的,但是25是一個最簡單、最基礎的端口號,所以我們填25

連接服務器就講完了,馬上來看第1和第2步:通過賬號和密碼登錄郵箱;填寫收件人。

來看登錄郵箱的代碼(第11行為新增代碼):

import smtplib 
#smtplib是python的一個內置庫,所以不需要用pip安裝
mailhost='smtp.qq.com'
#把qq郵箱的服務器地址賦值到變量mailhost上
qqmail = smtplib.SMTP()
#實例化一個smtplib模塊里的SMTP類的對象,這樣就可以SMTP對象的方法和屬性了
qqmail.connect(mailhost,25)
#連接服務器,第一個參數是服務器地址,第二個參數是SMTP端口號。
#以上,皆為連接服務器的代碼

account = input('請輸入你的郵箱:')
#獲取郵箱賬號
password = input('請輸入你的密碼:')
#獲取郵箱密碼
qqmail.login(account,password)
#登錄郵箱,第一個參數為郵箱賬號,第二個參數為郵箱密碼    

receiver=input('請輸入收件人的郵箱:')
#獲取收件人的郵箱

解釋一下從11行新增的代碼:第11行是用input()獲取郵箱賬號。第12行是用input()獲取郵箱密碼,但注意了,這里可不是你平時登錄郵箱的密碼!

這個密碼需要我們去到這里獲取:請打開https://mail.qq.com/,登錄你的郵箱。然后點擊位於頂部的【設置】按鈕,選擇【賬戶設置】,然后下拉到這個位置。

就像上面的一樣,把首個SMTP服務開啟。這時,QQ郵箱會提供給你一個授權碼,注意保護好你的授權碼:

接下來,在你使用SMTP服務登錄郵箱時,就可以輸入這個授權碼作為密碼登錄了。

繼續看第3步和第4步:填寫主題和撰寫正文,在這里需要用到email庫。

 1 from email.mime.text import MIMEText
 2 from email.header import Header
 3 #引入Header和MIMEText模塊
 4 content=input('請輸入郵件正文:')
 5 #輸入你的郵件正文
 6 message = MIMEText(content, 'plain', 'utf-8')
 7 #實例化一個MIMEText郵件對象,該對象需要寫進三個參數,分別是郵件正文,文本格式和編碼.
 8 subject = input('請輸入你的郵件主題:')
 9 #用input()獲取郵件主題  
10 message['Subject'] = Header(subject, 'utf-8')
11 #在等號的右邊,是實例化了一個Header郵件頭對象,該對象需要寫入兩個參數,分別是郵件主題和編碼,然后賦值給等號左邊的變量message['Subject']。

解釋一下:第1行和第2行代碼是引入了email庫中的MIMEText模塊和Header模塊。

第4行代碼是用input()函數獲取郵件正文,第6行代碼是實例化一個MIMEText的郵件對象,這樣我們就構造了一個純文本郵件了。

這個MIMEText對象有三個參數,一個是郵件正文;另一個是文本格式,一般設置為plain純文本格式;最后一個是編碼,設置為utf-8,因為utf-8是最流行的萬國碼。

繼續看第8行代碼,是用input()函數獲取郵件主題,第10行代碼比較重要,我們仔細講解一下:message['Subject'] = Header(subject, 'utf-8')

等號右邊是實例化了一個Header郵件頭對象,該對象需要寫入兩個參數,分別是郵件主題和編碼。

等號左邊的message['Subject']的變量是一個a['b']的代碼形式,它長得特別像字典根據鍵取值的表達,但是這里的message是一個MIMEText類的對象,並不是一個字典,那message['Subject']是什么意思呢?

其實,字典和類在結構上,有相似之處。請看下圖:

需要注意的是,不是每一個類都可以這樣訪問其屬性的,之所以能這樣訪問是因為這個MIMEText的類實現了這個功能。

所以,message['Subject'] = Header(subject, 'utf-8') 就是在為message['Subject']這個屬性賦值。

 1 import smtplib 
 2 #smtplib是python的一個內置庫,所以不需要用pip安裝
 3 mailhost='smtp.qq.com'
 4 #把qq郵箱的服務器地址賦值到變量mailhost上
 5 qqmail = smtplib.SMTP()
 6 #實例化一個smtplib模塊里的SMTP類的對象,這樣就可以SMTP對象的方法和屬性了
 7 qqmail.connect(mailhost,25)
 8 #連接服務器,第一個參數是服務器地址,第二個參數是SMTP端口號。
 9 #以上,皆為連接服務器的代碼
10 
11 account = input('請輸入你的郵箱:')
12 #獲取郵箱賬號
13 password = input('請輸入你的密碼:')
14 #獲取郵箱密碼
15 qqmail.login(account,password)
16 #登錄郵箱,第一個參數為郵箱賬號,第二個參數為郵箱密碼    
17 
18 receiver=input('請輸入收件人的郵箱:')
19 #獲取收件人的郵箱
20 
21 from email.mime.text import MIMEText
22 from email.header import Header
23 #引入Header和MIMEText模塊
24 content=input('請輸入郵件正文:')
25 #輸入你的郵件正文
26 message = MIMEText(content, 'plain', 'utf-8')
27 #實例化一個MIMEText郵件對象,該對象需要寫進三個參數,分別是郵件正文,文本格式和編碼.
28 subject = input('請輸入你的郵件主題:')
29 #用input()獲取郵件主題  
30 message['Subject'] = Header(subject, 'utf-8')
31 #在等號的右邊,是實例化了一個Header郵件頭對象,該對象需要寫入兩個參數,分別是郵件主題和編碼,然后賦值給等號左邊的變量message['Subject']。
32 
33 qqmail.sendmail(sender, receiver, message.as_string())
34 #發送郵件,調用了sendmail()方法,寫入三個參數,分別是發件人,收件人,和字符串格式的正文。
35 qqmail.quit()
36 #退出郵箱

解釋一下:第33行代碼的意思是調用sendmail()發送郵件,括號里面有三個參數,第0個是發件人的郵箱地址,第1個是收件人的郵箱地址,第2個是正文,但必須是字符串格式,所以用as_string()函數轉換了一下。

但是我們希望發送成功后能顯示“郵件發送成功”,失敗的時候能提示我們“郵件發送

1 try:
2     qqmail.sendmail(sender, receiver, message.as_string())
3     print ('郵件發送成功')
4 except:
5     print ('郵件發送失敗')
6 qqmail.quit()    

失敗”,可以使用try語句來實現。

2.定時

關於時間,其實Python有兩個內置的標准庫——timedatetime(我們在基礎課也學過time.sleep())。

但在這里,我們不准備完全依靠標准庫來實現,而准備選取第三方庫——schedule

原因在於:標准庫一般意味着最原始最基礎的功能,第三方庫很多是去調用標准庫中封裝好了的操作函數。比如schedule,就是用timedatetime來實現的。

而對於我們需要的定時功能,timedatetime當然能實現,但操作邏輯會相對復雜;而schedule就是可以直接解決定時功能,代碼比較簡單,這是我們選擇schedule的原因。

馬上來看代碼,官方文檔上的代碼也很簡潔,你可以先嘗試着自己閱讀一下,思考后點擊enter繼續:

 1 import schedule
 2 import time
 3 #引入schedule和time
 4 
 5 def job():
 6     print("I'm working...")
 7 #定義一個叫job的函數,函數的功能是打印'I'm working...'
 8 
 9 schedule.every(10).minutes.do(job)       #部署每10分鍾執行一次job()函數的任務
10 schedule.every().hour.do(job)            #部署每×小時執行一次job()函數的任務
11 schedule.every().day.at("10:30").do(job) #部署在每天的10:30執行job()函數的任務
12 schedule.every().monday.do(job)          #部署每個星期一執行job()函數的任務
13 schedule.every().wednesday.at("13:15").do(job)#部署每周三的13:15執行函數的任務
14 
15 while True:
16     schedule.run_pending()
17     time.sleep(1)    
18 #13-15都是檢查部署的情況,如果任務准備就緒,就開始執行任務。   

第1行和第2行,是引入scheduletime

第5行和第6行,是定義了一個叫job()的函數,調用這個函數時,函數會打印I'm working...

第9行-13行都是相關的時間設置,你可以根據自己的需要來確定。

第15-17行是一個while循環,是去檢查上面的任務部署情況,如果任務已經准備就緒,就去啟動執行。其中,第15行的time.sleep(1)是讓程序按秒來檢查,如果檢查太快,會浪費計算機的資源。

為了展示一下schedule的作用,我們看下面這段代碼:是每兩秒就運行job()函數。

import schedule
import time
#引入schedule和time模塊
def job():
    print("I'm working...")
#定義一個叫job的函數,函數的功能是打印'I'm working...'
schedule.every(2).seconds.do(job)        #每2s執行一次job()函數

while True:
    schedule.run_pending()
    time.sleep(1)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM