標籤:iss pytho 關係 頭資訊 很多 set cat ref 密碼
原理
網上已經有了很多的教程講解相關的發送郵件的原理,在這裡還是推薦一下廖雪峰老師的Python教程,講解通俗易懂。簡要來說,SMTP是發送郵件的協議,Python內建對SMTP的支援,可以發送純文字郵件、HTML郵件以及帶附件的郵件。而python內建的email模組則是負責郵件的內容、發送方、接收方等內容;具體的操作可以看代碼。
而構造一個郵件對象就是一個Messag對象,如果構造一個MIMEText對象,就表示一個文本郵件對象,如果構造一個MIMEImage對象,就表示一個作為附件的圖片,要把多個對象組合起來,就用MIMEMultipart對象,而MIMEBase可以表示任何對象。他們的嵌套關係如下:
Message+- MIMEBase +- MIMEMultipart +- MIMENonMultipart +- MIMEMessage +- MIMEText +- MIMEImage
一些錯誤的總結
[1]提示smtplib.SMTPAuthenticationError: (550, b‘User has no permission‘)
這是因為郵箱沒有開啟用戶端授權,郵箱這邊的SMTP服務運行不起來;而現在基本所有的郵件都是需要用戶端授權的,這裡需要注意一下。解決辦法為:進入163郵箱-設定-用戶端授權密碼-開啟(授權碼是用於登入第三方郵件用戶端的專用密碼),非第三方登入密碼不變。
[2]提示smtplib.SMTPAuthenticationError: (535, b‘Error: authentication failed‘)
以163郵箱為例,在開啟POP3/SMTP服務,並開啟用戶端授權密碼時會設定授權碼,將這個授權碼代替smtplib.SMTP().login(user,password)方法中的password即可。就是說你代碼中的password為你所設定的授權碼。
[3]提示554
說明郵件內容缺少資訊,在現在的郵箱裡一般有些內容需要填寫。
代碼
# 發送文本# -*- coding: utf-8 -*-from email import encodersfrom email.header import Headerfrom email.mime.text import MIMETextfrom email.utils import parseaddr, formataddrimport smtplibdef _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))from_addr = input('From: ')password = input('Password: ')to_addr = input('To: ')smtp_server = input('SMTP server: ')# 發的內容msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')# 寄件者msg['From'] = _format_addr(u'Python愛好者 <%s>' % from_addr)# 收件者msg['To'] = _format_addr(u'管理員 <%s>' % to_addr)# 標題msg['Subject'] = Header(u'來自SMTP的問候……', 'utf-8').encode()server = smtplib.SMTP(smtp_server, 25)server.set_debuglevel(1)server.login(from_addr, password)server.sendmail(from_addr, [to_addr], msg.as_string())server.quit()
# 發送附件# -*- coding: utf-8 -*-from email import encodersfrom email.header import Headerfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom email.mime.base import MIMEBasefrom email.utils import parseaddr, formataddrimport smtplibdef _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))from_addr = input('From: ')password = input('Password: ')to_addr = input('To: ')smtp_server = input('SMTP server: ')# 郵件對象:msg = MIMEMultipart()msg['From'] = _format_addr(u'Python愛好者 <%s>' % from_addr)msg['To'] = _format_addr(u'管理員 <%s>' % to_addr)msg['Subject'] = Header(u'來自SMTP的問候……', 'utf-8').encode()# 郵件內文是MIMEText:msg.attach(MIMEText('send with file...', 'plain', 'utf-8'))# 添加附件就是加上一個MIMEBase,從本地讀取一個圖片:with open('e:/141.m4a', 'rb') as f: # 設定附件的MIME和檔案名稱,這裡是音樂類型: mime = MIMEBase('image', 'm4a', filename='141.m4a') # 加上必要的頭資訊: mime.add_header('Content-Disposition', 'attachment', filename='141.m4a') mime.add_header('Content-ID', '<0>') mime.add_header('X-Attachment-Id', '0') # 把附件的內容讀進來: mime.set_payload(f.read()) # 用Base64編碼: encoders.encode_base64(mime) # 添加到MIMEMultipart: msg.attach(mime)server = smtplib.SMTP(smtp_server, 25)server.set_debuglevel(1)server.login(from_addr, password)server.sendmail(from_addr, [to_addr], msg.as_string())server.quit()
代碼經筆者都測試過,應該是沒問題的。遇到錯誤看看是不是用戶端的授權問題,或者是python的版本的問題。
利用Python的smtplib和email發送郵件