本例使用的時python2.7環境,python3的操作應該也是差不多的。 需要用到smtplib和email兩個包。 發送文本類型的郵件 下麵看個發送文本郵件的例子(使用網易163的SMTP): 好像網易的SMTP有坑,message['From']和message['To']都要和sender和 ...
本例使用的時python2.7環境,python3的操作應該也是差不多的。
需要用到smtplib和email兩個包。
發送文本類型的郵件
下麵看個發送文本郵件的例子(使用網易163的SMTP):
# -*- 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 = "[email protected]" # 發送者郵箱
mail_pass = "******" # 郵箱的客戶端授權碼
sender = "[email protected]" # 郵件的發送者
recivers = ["[email protected]", "[email protected]"] # 郵件接收者,可以指定多個
# 三個參數:第一個為文本內容,第二個設置文本格式,第三個設置字元編碼
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 = "[email protected]" # 發送者郵箱
mail_pass = "******" # 郵箱的客戶端授權碼
sender = "[email protected]"
recivers = ["[email protected]", "[email protected]"] # 接收郵件
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 = "[email protected]"
mail_pass = "******"
sender = "[email protected]"
recivers = ["[email protected]", "[email protected]"] # 接收郵件
# 創建附件實例
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狀態碼:
發送失敗返回的554:
總結
搞這些操作一是想弄明白智能合約CTF里怎麼實現用郵箱發來flag的,再一個就是想補補編程(你打代碼像cxk.gif)。
總之在裡面遇到很多坑,而且大部分都是返回的554(可能被判為垃圾郵件而攔截掉了),這裡的原因大概率是因為Subject有些文字不符(像“test"這種都會被攔截)。還有在批量發送時,recivers是一個list,那麼message['To']中需要用逗號和join()函數轉成字元串。
over!