Python傳送郵件


簡單郵件傳輸協定(SMTP)是一種協定,用於在郵件伺服器之間傳送電子郵件和路由電子郵件。

Python提供smtplib模組,該模組定義了一個SMTP用戶端對談物件,可用於使用SMTP或ESMTP偵聽器守護程式向任何網際網路機器傳送郵件。

這是一個簡單的語法,用來建立一個SMTP物件,稍後將演示如何用它來傳送電子郵件 -

import smtplib

smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

這裡是上面語法的引數細節 -

  • host - 這是執行SMTP伺服器的主機。可以指定主機的IP地址或類似tw511.com的域名。這是一個可選引數。
  • port - 如果提供主機引數,則需要指定SMTP伺服器正在偵聽的埠。通常這個埠預設值是:25
  • local_hostname - 如果SMTP伺服器在本地計算機上執行,那麼可以只指定localhost選項。

SMTP物件有一個sendmail的範例方法,該方法通常用於執行郵件傳送的工作。它需要三個引數 -

  • sender - 具有發件人地址的字串。
  • receivers - 字串列表,每個收件人一個。
  • message - 作為格式如在各種RFC中指定的字串。

1.使用Python傳送純文字電子郵件

範例

以下是使用Python指令碼傳送一封電子郵件的簡單方法 -

#!/usr/bin/python3

import smtplib

sender = '[email protected]'
receivers = ['[email protected]']

message = """From: From Person <[email protected]>
To: To Person <[email protected]>
Subject: SMTP e-mail test

This is a test e-mail message.
"""

try:
   smtpObj = smtplib.SMTP('localhost')
   smtpObj.sendmail(sender, receivers, message)         
   print "Successfully sent email"
except SMTPException:
   print "Error: unable to send email"

在這裡,已經傳送了一封基本的電子郵件,使用三重引號,請注意正確格式化標題。一封電子郵件需要一個FromTo和一個Subject標題,與電子郵件的正文與空白行分開。

要傳送郵件,使用smtpObj連線到本地機器上的SMTP伺服器。 然後使用sendmail方法以及訊息,從地址和目標地址作為引數(即使來自和地址在電子郵件本身內,這些並不總是用於路由郵件)。

如果沒有在本地計算機上執行SMTP伺服器,則可以使用smtplib用戶端與遠端SMTP伺服器進行通訊。除非您使用網路郵件服務(如gmail或Yahoo! Mail),否則您的電子郵件提供商必須向您提供可以提供的郵件伺服器詳細資訊。以騰訊QQ郵箱為例,具體如下:

mail = smtplib.SMTP('smtp.qq.com', 587) # 埠465或587

2.使用Python傳送HTML電子郵件

當使用Python傳送郵件資訊時,所有內容都被視為簡單文字。 即使在簡訊中包含HTML標籤,它也將顯示為簡單的文字,HTML標籤將不會根據HTML語法進行格式化。 但是,Python提供了將HTML訊息作為HTML訊息傳送的選項。

傳送電子郵件時,可以指定一個Mime版本,內容型別和傳送HTML電子郵件的字元集。
以下是將HTML內容作為電子郵件傳送的範例 -

#!/usr/bin/python3

import smtplib

message = """From: From Person <[email protected]>
To: To Person <[email protected]>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP HTML e-mail test

This is an e-mail message to be sent in HTML format

<b>This is HTML message.</b>
<h1>This is headline.</h1>
"""

try:
   smtpObj = smtplib.SMTP('localhost')
   smtpObj.sendmail(sender, receivers, message)         
   print "Successfully sent email"
except SMTPException:
   print "Error: unable to send email"

3.傳送附件作為電子郵件

要傳送具有混合內容的電子郵件,需要將Content-type標題設定為multipart / mixed。 然後,可以在邊界內指定文字和附件部分。

一個邊界以兩個連字元開始,後跟一個唯一的編號,不能出現在電子郵件的訊息部分。 表示電子郵件最終部分的最後一個邊界也必須以兩個連字元結尾。

所附的檔案應該用包(「m」)功能編碼,以便在傳輸之前具有基本的64編碼。

4.傳送範例

首先我們要知道用python代理登入qq郵箱發郵件,是需要更改自己qq郵箱設定的。在這裡大家需要做兩件事情:郵箱開啟SMTP功能 、獲得授權碼。之後我們來看看如何更改模板程式碼,實現使用Python登入QQ郵箱傳送QQ郵件。

注意:也可以使用其他服務商的 SMTP 存取(QQ、網易、Gmail等)。

使用QQ郵件傳送郵件之前如何設定授權碼,參考:

http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256

4.1.傳送一純文字郵件到指定郵件

#! /usr/bin/env python
#coding=utf-8

from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL


#qq郵箱smtp伺服器
host_server = 'smtp.qq.com'
#sender_qq為發件人的qq號碼
sender_qq = '[email protected]'
#pwd為qq郵箱的授權碼
pwd = '****kenbb***' ## xh**********bdc
#發件人的郵箱
sender_qq_mail = '[email protected]'
#收件人郵箱
receiver = '[email protected]'

#郵件的正文內容
mail_content = '你好,這是使用python登入qq郵箱發郵件的測試'
#郵件標題
mail_title = 'Maxsu的郵件'

#ssl登入
smtp = SMTP_SSL(host_server)
#set_debuglevel()是用來偵錯的。引數值為1表示開啟偵錯模式,引數值為0關閉偵錯模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

msg = MIMEText(mail_content, "plain", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq_mail
msg["To"] = receiver
smtp.sendmail(sender_qq_mail, receiver, msg.as_string())
smtp.quit()

執行上面程式碼後,登入接收郵件的郵件帳號,這裡接收郵件的賬號為:[email protected],登入 http://gmail.com 應該會看到有接收到郵件如下 -

注意:有時可能被認為是垃圾郵件,如果沒有找到可從「垃圾郵件」查詢一下。

4.2.給多個人傳送郵件

#! /usr/bin/env python
#coding=utf-8

from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL


#qq郵箱smtp伺服器
host_server = 'smtp.qq.com'
#sender_qq為發件人的qq號碼
sender_qq = '[email protected]'
#pwd為qq郵箱的授權碼
pwd = 'h**********bdc' ## h**********bdc
#發件人的郵箱
sender_qq_mail = '[email protected]'
#收件人郵箱
receivers = ['[email protected]','****[email protected]']

#郵件的正文內容
mail_content = '你好,這是使用python登入qq郵箱發郵件的測試'
#郵件標題
mail_title = 'Maxsu的郵件'


#ssl登入
smtp = SMTP_SSL(host_server)
#set_debuglevel()是用來偵錯的。引數值為1表示開啟偵錯模式,引數值為0關閉偵錯模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

msg = MIMEText(mail_content, "plain", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq_mail
msg["To"] = Header("接收者測試", 'utf-8') ## 接收者的別名
smtp.sendmail(sender_qq_mail, receivers, msg.as_string())
smtp.quit()

執行上面程式碼後,登入接收郵件的郵件帳號,這裡接收郵件的賬號為:[email protected],登入 http://gmail.com 應該會看到有接收到郵件如下 -

4.3.使用Python傳送HTML格式的郵件

Python傳送HTML格式的郵件與傳送純文字訊息的郵件不同之處就是將MIMEText中_subtype設定為html。程式碼如下:

#! /usr/bin/env python
#coding=utf-8

from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL


#qq郵箱smtp伺服器
host_server = 'smtp.qq.com'
#sender_qq為發件人的qq號碼
sender_qq = '[email protected]'
#pwd為qq郵箱的授權碼
pwd = '***bmke********' ##
#發件人的郵箱
sender_qq_mail = '[email protected]'
#收件人郵箱
receiver = '[email protected]'

#郵件的正文內容
mail_content = "你好,<p>這是使用python登入qq郵箱傳送HTML格式郵件的測試:</p><p><a href='https://www.tw511.com'>易百教學</a></p>"
#郵件標題
mail_title = 'Maxsu的郵件'


#ssl登入
smtp = SMTP_SSL(host_server)
#set_debuglevel()是用來偵錯的。引數值為1表示開啟偵錯模式,引數值為0關閉偵錯模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

msg = MIMEText(mail_content, "html", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq_mail
msg["To"] = Header("接收者測試", 'utf-8') ## 接收者的別名

smtp.sendmail(sender_qq_mail, receiver, msg.as_string())
smtp.quit()

執行上面程式碼後,登入接收郵件的郵件帳號,這裡接收郵件的賬號為:[email protected],登入 http://gmail.com 應該會看到有接收到郵件如下 -

4.4.Python傳送帶附件的郵件

要傳送帶附件的郵件,首先要建立MIMEMultipart()範例,然後構造附件,如果有多個附件,可依次構造,最後使用smtplib.smtp傳送。

實現程式碼如下所示 -

#! /usr/bin/env python
#coding=utf-8
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header



#qq郵箱smtp伺服器
host_server = 'smtp.qq.com'
#sender_qq為發件人的qq號碼
sender_qq = '[email protected]'
#pwd為qq郵箱的授權碼
pwd = '*****mkenb****' ##
#發件人的郵箱
sender_qq_mail = '[email protected]'
#收件人郵箱
receiver = '[email protected]'

#郵件的正文內容
mail_content = "你好,<p>這是使用python登入qq郵箱傳送HTML格式郵件的測試:</p><p><a href='https://www.tw511.com'>易百教學</a></p>"
#郵件標題
mail_title = 'Maxsu的郵件'

#郵件正文內容
msg = MIMEMultipart()
#msg = MIMEText(mail_content, "plain", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq_mail
msg["To"] = Header("接收者測試", 'utf-8') ## 接收者的別名

#郵件正文內容
msg.attach(MIMEText(mail_content, 'html', 'utf-8'))


# 構造附件1,傳送當前目錄下的 test.txt 檔案
att1 = MIMEText(open('attach.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 這裡的filename可以任意寫,寫什麼名字,郵件中顯示什麼名字
att1["Content-Disposition"] = 'attachment; filename="attach.txt"'
msg.attach(att1)

# 構造附件2,傳送當前目錄下的 runoob.txt 檔案
att2 = MIMEText(open('yiibai.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="yiibai.txt"'
msg.attach(att2)


#ssl登入
smtp = SMTP_SSL(host_server)
#set_debuglevel()是用來偵錯的。引數值為1表示開啟偵錯模式,引數值為0關閉偵錯模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

smtp.sendmail(sender_qq_mail, receiver, msg.as_string())
smtp.quit()

執行上面程式碼後,登入接收郵件的郵件帳號,這裡接收郵件的賬號為:[email protected],登入 http://gmail.com 應該會看到有接收到郵件如下 -

4.5.在 HTML 文字中新增圖片

郵件的HTML文字中一般郵件服務商新增外連是無效的,所以要傳送帶圖片的郵件內容,可以參考下面的範例程式碼實現:

#! /usr/bin/env python
#coding=utf-8
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL

from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


#qq郵箱smtp伺服器
host_server = 'smtp.qq.com'
#sender_qq為發件人的qq號碼
sender_qq = '[email protected]'
#pwd為qq郵箱的授權碼
pwd = 'h******mk*****' #
#發件人的郵箱
sender_qq_mail = '[email protected]'
#收件人郵箱
receiver = ['[email protected]','h****[email protected]']

#郵件的正文內容
mail_content = ""
#郵件標題
mail_title = 'Maxsu的郵件'

#郵件正文內容
#msg = MIMEMultipart()
msg = MIMEMultipart('related')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq_mail
msg["To"] = Header("接收者測試", 'utf-8') ## 接收者的別名

msgAlternative = MIMEMultipart('alternative')
msg.attach(msgAlternative)


#郵件正文內容
mail_body = """
 <p>你好,Python 郵件傳送測試...</p>
 <p>這是使用python登入qq郵箱傳送HTML格式和圖片的測試郵件:</p>
 <p><a href='https://www.tw511.com'>易百教學</a></p>
 <p>圖片演示:</p>
 <p><img src="cid:send_image"></p>
"""

#msg.attach(MIMEText(mail_body, 'html', 'utf-8'))
msgText = (MIMEText(mail_body, 'html', 'utf-8'))
msgAlternative.attach(msgText)


# 指定圖片為當前目錄
fp = open('my.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()

# 定義圖片 ID,在 HTML 文字中參照
msgImage.add_header('Content-ID', '<send_image>')
msg.attach(msgImage)


#ssl登入
smtp = SMTP_SSL(host_server)
#set_debuglevel()是用來偵錯的。引數值為1表示開啟偵錯模式,引數值為0關閉偵錯模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

smtp.sendmail(sender_qq_mail, receiver, msg.as_string())
smtp.quit()

執行上面程式碼後,登入接收郵件的郵件帳號,這裡接收郵件的賬號為:[email protected],登入 http://gmail.com 應該會看到有接收到郵件如下 -