python SMTP郵件發送

本例使用的時python2.7環境,python3的操做應該也是差很少的。
須要用到smtplib和email兩個包。html

發送文本類型的郵件

下面看個發送文本郵件的例子(使用網易163的SMTP):python

# -*- coding: UTF-8 -*-

import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formataddr

# 第三方SMTP
mail_host = "smtp.163.com" # SMTP服務器
mail_user = "sender@163.com" # 發送者郵箱
mail_pass = "******" # 郵箱的客戶端受權碼

sender = "sender@163.com" # 郵件的發送者
recivers = ["bob@qq.com", "someone@gmail.com"] # 郵件接收者,能夠指定多個

# 三個參數:第一個爲文本內容,第二個設置文本格式,第三個設置字符編碼
message = MIMEText('Python郵件發送測試', 'plain', 'utf-8')
message['From'] = sender;
# == message['From'] = formataddr(['sender', sender])
message['To'] = ", ".join(recivers)
# == message['To] = formataddr(['ok', ', '.join(recivers)])
subject = 'Python 郵件測試'
message['Subject'] = Header(subject, 'utf-8')

try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mali_host, 25) # 鏈接SMTP,端口爲25
    smtpObj.set_debuglevel(1)
    smtpObj.login(mail_user, mail_pass)
    smtpObj.sendmail(sender, recivers,message.as_string())
    print "emails send successfully"
except smtplib.SMTPException:
    print "Error:cannot send emails"
smtpObj.quit() # 關閉鏈接

好像網易的SMTP有坑,message['From']和message['To']都要和sender和recivers一致才能夠,還有標題和內容儘可能不要有敏感詞,不然會被服務器判爲垃圾郵件而發不出去,我第一次就由於Subject帶有「SMTP」而被攔截(滑稽.gif)。
若是郵件發送失敗,能夠查看set_debuglevel()函數返回的狀態碼來斷定什麼緣由。編程

發送HTML格式的郵件

與發送文本不一樣的地方就是將MIMEText中的_subtype設爲html,發送帶圖片的HTML還要建立MIMEMultipart()實例。服務器

# -*- coding: UTF-8 -*-

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage

# 第三方SMTP
mail_host = "smtp.163.com" # SMTP服務器
mail_user = "sender@163.com" # 發送者郵箱
mail_pass = "******" # 郵箱的客戶端受權碼

sender = "sender@163.com"
recivers = ["bob@qq.com", "alice@qq.com"]  # 接收郵件

msg = MIMEMultipart('related')
msg['From'] = sender
msg['To'] = ", ".join(recivers)
subject = 'HTML 1m4g3'
msg['Subject'] = Header(subject, 'utf-8')
mail_msg = """
<h1>HTML image測試</h1>
<p><a href="http://www.baidu.com">learn more</a></p>
<p><img src="cid:image1"></p>
"""
msgAlternative = MIMEMultipart('alternative')
msg.attach(msgAlternative)
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))

# 指定當前目錄的圖片
fp = open('test1.gif', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()

# 定義圖片ID,在HTML中引用
msgImage.add_header('Content-ID', '<image1>')
msg.attach(msgImage)

try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mail_host, 25)  # 25 SMTP Port
    smtpObj.set_debuglevel(1)
    smtpObj.login(mail_user, mail_pass)
    smtpObj.sendmail(sender, recivers, msg.as_string())
    print "emails send sucessfully"

except smtplib.SMTPException:
    print "Error:cannot send emails"
smtpObj.quit()

發送帶附件的郵件

# -*- coding: UTF-8 -*-

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage

# 第三方SMTP
mail_host = "smtp.163.com"  # 設置服務器
mail_user = "sender@163.com"
mail_pass = "******"

sender = "sender@163.com"
recivers = ["bob@qq.com", "alice@qq.com"]  # 接收郵件

# 建立附件實例
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = ", ".join(recivers)
subject = '郵件附件'
msg['Subject'] = Header(subject, 'utf-8')
# 郵件正文:
MIMEText('郵件正文以下', 'html', 'utf-8')

# 構造附件,傳送當前目錄下的txt文件:
att1 = MIMEText(open('test1.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 這裏的filename能夠任意命名,成爲郵件中顯示的文件名
att1["Content-Disposition"] = 'attachment;filename="test_1.txt"'
msg.attach(att1)

try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mail_host, 25)  # 25 SMTP Port
    smtpObj.set_debuglevel(1)
    smtpObj.login(mail_user, mail_pass)
    smtpObj.sendmail(sender, recivers, msg.as_string())
    print "emails send sucessfully"

except smtplib.SMTPException:
    print "Error:cannot send emails"

smtpObj.quit()

發送正常的就會返回250狀態碼:
app

發送失敗返回的554:
python2.7

總結

搞這些操做一是想弄明白智能合約CTF裏怎麼實現用郵箱發來flag的,再一個就是想補補編程(你打代碼像cxk.gif)。
總之在裏面遇到不少坑,並且大部分都是返回的554(可能被判爲垃圾郵件而攔截掉了),這裏的緣由大機率是由於Subject有些文字不符(像「test"這種都會被攔截)。還有在批量發送時,recivers是一個list,那麼message['To']中須要用逗號和join()函數轉成字符串。
over!函數

相關文章
相關標籤/搜索