一些概念
MUA:Mail User Agent——郵件使用者代理,例如OutLook、Foxmail
MTA:Mail Transfer Agent——郵件傳輸代理,例如163.com、sina.com這些Email服務提供商
MDA:Mail Delivery Agent——郵件投遞代理,郵件投遞的最終目的地、就像一個儲存有點的資料庫一樣
郵件收發過程
send@163.com -> MUA -> MTA -> MTA -> 若干個MTA -> MDA <- MUA <- receive@sina.com
1. 寫郵件:通過MUA這樣的軟體完成,並由MUA負責傳送
2. 傳輸過程:自己的電子郵件是@163.com,所以會首先被投遞給網易提供的MTA,再由網易的MTA傳送給新浪的MTA,中間可能還會經過別的MTA
3. 投遞到最終目的地:最終新浪的MTA會把Email投遞到MDA中,就相當於傳送到了receive@sina.com這個電子郵箱中了,這封Email內容被放到了新浪的某個伺服器(資料庫)上
4. 收件人看到郵件內容:Email之所以不會直接到達對方的電腦,就因為對方電腦不一定開機,開機也不一定聯網,那最終收件人提取郵件時,是通過MUA從MDA上獲取的
協議
發郵件時:
MUA通過SMTP協議將Email傳送到MTA
發郵件時需要先配置SMTP伺服器,例如163提供的SMTP伺服器地址:smtp.163.com
為了證明你是163.com使用者,MTA需要驗證SMTP伺服器地址、郵箱地址、口令
收郵件時:
MUA從MDA收郵件使用的協議有兩種:POP3 / IMAP(IMAP不但能讀取郵件還能直接操作MDA上儲存的郵件)
為了防止你冒充他人收郵件,MDA需要驗證POP3/IMAP伺服器地址、郵箱地址、口令
傳送普通文字郵件
from email import encoders from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr,formataddr import smtplib mail_send='******@163.com' mail_passwd='******' #這是授權口令密碼,不是郵箱登入密碼 mail_smtp='smtp.163.com' main_to=['******@**.com','******@163.com'] def _format_addr(s): name,addr=parseaddr(s) return formataddr((Header(name,'utf-8').encode(),addr)) '''Python2應該這這麼寫 def _format_addr(s): name,addr=parseaddr(s) return formataddr(( Header(name, 'utf-8').encode(), addr.encode('utf-8') if isinstance(addr, unicode) else addr)) ''' def send_mail(to_list,subject,content): msg=MIMEText(content,'plain','utf-8') msg['Subject']=Header(subject,'utf-8') msg['From']=_format_addr("我是發件人 <{}>".format(mail_send)) # Python2: msg['From']=_format_addr('我是發件人 <%s>' % mail_send) # msg['To']=",".join(to_list) try: server=smtplib.SMTP() server.connect(mail_smtp) server.login(mail_send,mail_passwd) server.sendmail(mail_send,to_list,msg.as_string()) server.close() except Exception: print("Error") send_mail(main_to,"傳送測試","郵件傳送文字成功")
傳送帶附件的郵件
def send_mail_accessory(to_list,subject,content,filename): msg=MIMEMultipart() msg['Subject']=Header(subject,'utf-8') msg['From']=_format_addr("我是發件人 <{}>".format(mail_send)) msg['To']=",".join(to_list) msg.attach(MIMEText(content,'plain','utf-8')) with open(filename,mode='rb') as f: mime=MIMEBase('excel','xlsx',filename=filename.split('/')[2]) mime.add_header('content-disposition','attachment', filename=filename.split('/')[2]) mime.add_header('Content-ID', '<0>') mime.add_header('X-Attachment-Id', '0') mime.set_payload(f.read()) encoders.encode_base64(mime) msg.attach(mime) server=smtplib.SMTP() server.connect(mail_smtp) server.login(mail_send,mail_passwd) server.sendmail(mail_send,to_list,msg.as_string()) server.close() send_mail_accessory(mail_to,"發附件測試","給你發了一個檔案","/py3/xxx.xlsx")