1. 程式人生 > >利用Python的smtplib和email發送郵件

利用Python的smtplib和email發送郵件

odi rmi mtp 測試 div read 關系 format 三方登錄

原理

網上已經有了很多的教程講解相關的發送郵件的原理,在這裏還是推薦一下廖雪峰老師的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 encoders
from
email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr, formataddr import smtplib def _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 encoders
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.utils import parseaddr, formataddr
import smtplib

def _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發送郵件