一、說明
1.1 程序說明
(1)smtp是郵件發送協議;pop和imap都是郵件接收協議,兩者的區別通常的說法是imap的操作會同步到郵箱服務器而pop不會,表現上我也不是很清楚
(2)本程序實現使用smtplib標准庫實現郵件發送、使用poplib標准庫和imaplib標准庫實現郵件收取
(3)具體到代碼上,三個功能依次對應程序中的send_email_by_smtp()、recv_email_by_pop3()、recv_email_by_imap4()三個函數,這三個函數相互獨立沒有調用關系
(4)由於還沒弄清楚要怎么能很好地解碼郵件,所以這里的pop和imap都只是直接將最新的一封郵件讀取后直接打印出來,並沒有進行解碼。
(5)在貼上代碼時,代碼中的郵箱已全部替換,使用時記得修改這些信息;注釋中已都有較詳細說明,不多輟述。
(6)對於自己郵箱的smtp服端器、pop服務器、imap服務器地址如果不知道則自己百度一下,一般都是“協議+郵箱后輟”的形式(比如pop.qq.com),這種形式如果能ping通一般就是了;端口則可能多變,如果查不到就直接nmap等工具掃一下。比如下面:
1.2 程序運行截圖
smtp郵件發送截圖:
pop3郵件收取截圖:
imap4郵件收取截圖:
二、程序代碼
import smtplib import poplib import imaplib from email.mime.text import MIMEText from email.header import Header class operate_email: # 此函數通過使用smtplib實現發送郵件 def send_email_by_smtp(self): # 用於發送郵件的郵箱。修改成自己的郵箱 sender_email_address = "your_email@qq.com" # 用於發送郵件的郵箱的密碼。修改成自己的郵箱的密碼 sender_email_password = "your_email_password" # 用於發送郵件的郵箱的smtp服務器,也可以直接是IP地址 # 修改成自己郵箱的sntp服務器地址;qq郵箱不需要修改此值 smtp_server_host = "smtp.qq.com" # 修改成自己郵箱的sntp服務器監聽的端口;qq郵箱不需要修改此值 smtp_server_port = 465 # 要發往的郵箱 receiver_email = "your_dest_email@qq.com" # 要發送的郵件主題 message_subject = "Python smtp測試郵件" # 要發送的郵件內容 message_context = "這是一封通過Python smtp發送的測試郵件..." # 郵件對象,用於構建郵件 # 如果要發送html,請將plain改為html message = MIMEText(message_context, 'plain', 'utf-8') # 設置發件人(聲稱的) message["From"] = Header(sender_email_address, "utf-8") # 設置收件人(聲稱的) message["To"] = Header(receiver_email, "utf-8") # 設置郵件主題 message["Subject"] = Header(message_subject,"utf-8") # 連接smtp服務器。如果沒有使用SSL,將SMTP_SSL()改成SMTP()即可其他都不需要做改動 email_client = smtplib.SMTP_SSL(smtp_server_host, smtp_server_port) try: # 驗證郵箱及密碼是否正確 email_client.login(sender_email_address, sender_email_password) print("smtp----login success, now will send an email to {receiver_email}") except: print("smtp----sorry, username or password not correct or another problem occur") else: # 發送郵件 email_client.sendmail(sender_email_address, receiver_email, message.as_string()) print(f"smtp----send email to {receiver_email} finish") finally: # 關閉連接 email_client.close() # 此函數通過使用poplib實現接收郵件 def recv_email_by_pop3(self): # 要進行郵件接收的郵箱。改成自己的郵箱 email_address = "your_email@qq.com" # 要進行郵件接收的郵箱的密碼。改成自己的郵箱的密碼 email_password = "your_email_password" # 郵箱對應的pop服務器,也可以直接是IP地址 # 改成自己郵箱的pop服務器;qq郵箱不需要修改此值 pop_server_host = "pop.qq.com" # 郵箱對應的pop服務器的監聽端口。改成自己郵箱的pop服務器的端口;qq郵箱不需要修改此值 pop_server_port = 995 try: # 連接pop服務器。如果沒有使用SSL,將POP3_SSL()改成POP3()即可其他都不需要做改動 email_server = poplib.POP3_SSL(host=pop_server_host, port=pop_server_port, timeout=10) print("pop3----connect server success, now will check username") except: print("pop3----sorry the given email server address connect time out") exit(1) try: # 驗證郵箱是否存在 email_server.user(email_address) print("pop3----username exist, now will check password") except: print("pop3----sorry the given email address seem do not exist") exit(1) try: # 驗證郵箱密碼是否正確 email_server.pass_(email_password) print("pop3----password correct,now will list email") except: print("pop3----sorry the given username seem do not correct") exit(1) # 郵箱中其收到的郵件的數量 email_count = len(email_server.list()[1]) # 通過retr(index)讀取第index封郵件的內容;這里讀取最后一封,也即最新收到的那一封郵件 resp, lines, octets = email_server.retr(email_count) # lines是郵件內容,列表形式使用join拼成一個byte變量 email_content = b'\r\n'.join(lines) # 再將郵件內容由byte轉成str類型 email_content = email_content.decode() print(email_content) # 關閉連接 email_server.close() # 此函數通過使用imaplib實現接收郵件 def recv_email_by_imap4(self): # 要進行郵件接收的郵箱。改成自己的郵箱 email_address = "your_email@qq.com" # 要進行郵件接收的郵箱的密碼。改成自己的郵箱的密碼 email_password = "your_email_password" # 郵箱對應的imap服務器,也可以直接是IP地址 # 改成自己郵箱的imap服務器;qq郵箱不需要修改此值 imap_server_host = "imap.qq.com" # 郵箱對應的pop服務器的監聽端口。改成自己郵箱的pop服務器的端口;qq郵箱不需要修改此值 imap_server_port = 993 try: # 連接imap服務器。如果沒有使用SSL,將IMAP4_SSL()改成IMAP4()即可其他都不需要做改動 email_server = imaplib.IMAP4_SSL(host=imap_server_host, port=imap_server_port) print("imap4----connect server success, now will check username") except: print("imap4----sorry the given email server address connect time out") exit(1) try: # 驗證郵箱及密碼是否正確 email_server.login(email_address,email_password) print("imap4----username exist, now will check password") except: print("imap4----sorry the given email address or password seem do not correct") exit(1) # 郵箱中其收到的郵件的數量 email_server.select() email_count = len(email_server.search(None, 'ALL')[1][0].split()) # 通過fetch(index)讀取第index封郵件的內容;這里讀取最后一封,也即最新收到的那一封郵件 typ, email_content = email_server.fetch(f'{email_count}'.encode(), '(RFC822)') # 將郵件內存由byte轉成str email_content = email_content[0][1].decode() print(email_content) # 關閉select email_server.close() # 關閉連接 email_server.logout() if __name__ == "__main__": # 實例化 email_client = operate_email() # 調用通過smtp發送郵件的發送函數 email_client.send_email_by_smtp() # 調用通過pop3接收郵件的接收函數 email_client.recv_email_by_pop3() # 調用通過imap4接收郵件的接收函數 email_client.recv_email_by_imap4()
參考:
https://docs.python.org/3/library/smtplib.html
https://docs.python.org/3/library/poplib.html
https://docs.python.org/3/library/imaplib.html
http://help.163.com/10/0203/13/5UJONJ4I00753VB8.html
http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=371
http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=331