foxmail 怎么把邮件格式默认为html_Python SMTP发送邮件-smtplib模块
在進入正題之前,我們需要對一些基本內容有所了解:常用的電子郵件協議有SMTP、POP3、IMAP4,它們都隸屬于TCP/IP協議簇,默認狀態下,分別通過TCP端口25、110和143建立連接。
Python內置對SMTP的支持,該協議支持發送純文本郵件、HTML郵件以及帶附件的郵件,
Python的smtplib,email模塊都支持該協議。
SMTP(Simple Mail Transfer Protocol)即簡單郵件傳輸協議,它是一組用于由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。
發郵件需要掌握兩個模塊的用法,smtplib和email,這倆模塊是python自帶的,只需import即可使用。
smtplib模塊主要負責發送郵件,email模塊主要負責構造郵件。
smtplib模塊主要負責發送郵件:是一個發送郵件的動作,連接郵箱服務器,登錄郵箱,發送郵件(有發件人,收信人,郵件內容)。
email模塊主要負責構造郵件:指的是郵箱頁面顯示的一些構造,如發件人,收件人,主題,正文,附件等。
第一步,首先你要準備兩個郵箱帳號,一個是常用的(接收端),另一個可以注冊網易163郵箱或者foxmail郵箱也可(發送端),
本次我使用兩個QQ郵箱進行演示。首先在郵箱的設置-賬戶中開啟SMTP功能第二步,點擊生成授權碼,按照彈出窗口的提示發送短信,發送后單擊我已發送按鈕。將生成的授權碼復制下來以備接下來使用。
QQ 郵箱 SMTP 服務器地址:http://smtp.qq.com,ssl 端口:465。授權碼是下面案例中的密碼
1.smtplib模塊
smtplib使用較為簡單。以下是最基本的語法。
導入及使用方法如下:
import smtplib smtp = smtplib.SMTP() smtp.connect('smtp.qq.com,465') smtp.login(username, password) smtp.sendmail(send_add, to_add, msg.as_string()) smtp.quit()說明:
smtplib.SMTP():實例化SMTP()
connect(host,port):
host:指定連接的郵箱服務器。常用郵箱的smtp服務器地址如下:
新浪郵箱:smtp.sina.com,
新浪VIP:smtp.vip.sina.com,
搜狐郵箱:http://smtp.sohu.com,
126郵箱:smtp.126.com,
139郵箱:smtp.139.com,
163網易郵箱:http://smtp.163.com。
port:指定連接服務器的端口號,默認為25. 默認很可能會失敗,端口號具體內容需要查詢郵件服務提供商
login(user,password):
user:登錄郵箱的用戶名。
password:登錄郵箱的密碼,像筆者用的是QQ郵箱,QQ郵箱一般是網頁版,需要用到客戶端密碼,需要在網頁版的QQ郵箱中設置授權碼,該授權碼即為客戶端密碼。
sendmail(from_addr,to_addrs,msg,...):
from_addr:郵件發送者地址
to_addrs:郵件接收者地址。字符串列表['接收地址1','接收地址2','接收地址3',...]或'接收地址'
msg:發送消息:郵件內容。一般是msg.as_string():as_string()是將msg(MIMEText對象或者MIMEMultipart對象)變為str。
quit():用于結束SMTP會話。
2.email模塊
email模塊下有mime包,mime英文全稱為“Multipurpose Internet Mail Extensions”,即多用途互聯網郵件擴展,是目前互聯網電子郵件普遍遵循的郵件技術規范。
該mime包下常用的有三個模塊:text*,image,*multpart。
導入方法如下:
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage構造一個郵件對象就是一個Message對象,
如果構造一個MIMEText對象,就表示一個文本郵件對象,
如果構造一個MIMEImage對象,就表示一個作為附件的圖片,
要把多個對象組合起來,就用MIMEMultipart對象,
而MIMEBase可以表示任何對象。它們的繼承關系如下:
2.1 text說明
郵件發送程序為了防止有些郵件閱讀軟件不能顯示處理HTML格式的數據,通常都會用兩類型分別為"text/plain"和"text/html"
構造MIMEText對象時,第一個參數是郵件正文,第二個參數是MIME的subtype,最后一定要用utf-8編碼保證多語言兼容性。
2.1.1添加普通文本text = "Hi!nHow are you?nHere is the link you wanted:nhttp://www.zhihu.com" text_plain = MIMEText(text,'plain', 'utf-8')查看MIMEText屬性:可以觀察到MIMEText,MIMEImage和MIMEMultipart的屬性都一樣。
print dir(text_plain)['contains', 'delitem', 'doc', 'getitem', 'init', 'len', 'module', 'setitem', 'str', '_charset', '_default_type', '_get_params_preserve', '_headers', '_payload', '_unixfrom', 'add_header', 'as_string', 'attach', 'defects', 'del_param', 'epilogue', 'get', 'get_all', 'get_boundary', 'get_charset', 'get_charsets', 'get_content_charset', 'get_content_maintype', 'get_content_subtype', 'get_content_type', 'get_default_type', 'get_filename', 'get_param', 'get_params', 'get_payload', 'get_unixfrom', 'has_key', 'is_multipart', 'items', 'keys', 'preamble', 'replace_header', 'set_boundary', 'set_charset', 'set_default_type', 'set_param', 'set_payload', 'set_type', 'set_unixfrom', 'values', 'walk']
import smtplib from email.mime.text import MIMEText from email.header import Header # 第三方 SMTP 服務 mail_host = "smtp.qq.com" # 設置服務器 mail_user = "******@qq.com" # 用戶名 mail_pass = "famaiqllddfsbjag" # 授權碼 sender = '******@qq.com' receivers = ['****@qq.com'] # 接收郵件,可設置為你的QQ郵箱或者其他郵箱 message = MIMEText('Python 郵件發送測試...', 'plain', 'utf-8') message['From'] = Header("Python SMTP教程", 'utf-8') #括號里的對應發件人郵箱昵稱(隨便起)、發件人郵箱賬號 message['To'] = Header("測試", 'utf-8') #括號里的對應收件人郵箱昵稱、收件人郵箱賬號 subject = 'Python SMTP 郵件測試' message['Subject'] = Header(subject, 'utf-8') try:smtpObj = smtplib.SMTP()smtpObj.connect(mail_host, 465) # 發件人郵箱中的SMTP服務器,端口是465smtpObj.login(mail_user, mail_pass)smtpObj.sendmail(sender, receivers, message.as_string())print("郵件發送成功") except smtplib.SMTPException:print("Error: 無法發送郵件")2.1.2添加超文本Python發送HTML格式的郵件與發送純文本消息的郵件不同之處就是將MIMEText中_subtype設置為html。具體代碼如下:
import smtplib from email.mime.text import MIMEText from email.header import Header # 第三方 SMTP 服務 mail_host = "smtp.qq.com" # 設置服務器 mail_user = "*********@qq.com" # 用戶名 mail_pass = "famaiqllddfsbjag" # 授權碼 sender = '********@qq.com' receivers = ['*********@qq.com'] # 接收郵件,可設置為你的QQ郵箱或者其他郵箱 #使用Python發送HTML格式的郵件 mail_msg = """ <p>Python 郵件發送測試...</p> <p><a href="http://www.zhihu.com">這是一個鏈接</a></p> """ message = MIMEText(mail_msg, 'html', 'utf-8') message['From'] = Header("Python smtp教程", 'utf-8') #括號里的對應發件人郵箱昵稱(隨便起)、發件人郵箱賬號 message['To'] = Header("測試", 'utf-8') #括號里的對應收件人郵箱昵稱、收件人郵箱賬號 subject = 'Python SMTP 郵件測試' message['Subject'] = Header(subject, 'utf-8') try:smtpObj = smtplib.SMTP()smtpObj.connect(mail_host, 465) # 發件人郵箱中的SMTP服務器,端口是465smtpObj.login(mail_user, mail_pass)smtpObj.sendmail(sender, receivers, message.as_string())print("郵件發送成功") except smtplib.SMTPException:print("Error: 無法發送郵件")2.1.3 image說明import smtplib from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.header import Header # 第三方 SMTP 服務 mail_host = "smtp.qq.com" # 設置服務器 mail_user = "****@qq.com" # 用戶名 mail_pass = "famaiqllddfsbjag" # 授權碼 sender = '*****@qq.com' receivers = ['*****@qq.com'] # 接收郵件,可設置為你的QQ郵箱或者其他郵箱 msgRoot = MIMEMultipart('related') msgRoot['From'] = Header("發送者", 'utf-8') msgRoot['To'] = Header("測試", 'utf-8') subject = 'Python SMTP 郵件測試' msgRoot['Subject'] = Header(subject, 'utf-8') msgAlternative = MIMEMultipart('alternative') msgRoot.attach(msgAlternative) mail_msg = """ <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Send mail Tets</title> </head> <body> <img src="cid:jpg1" width="400" height="400" alt=""> <br><br> </body> </html> """ msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8')) # 指定圖片為當前目錄 with open('4.jpg', 'rb') as image_file:msgImage = MIMEImage(image_file.read()) # 定義圖片 ID,在 HTML 文本中引用 msgImage.add_header('Content-ID', 'jpg1') msgRoot.attach(msgImage) try:smtpObj = smtplib.SMTP()smtpObj.connect(mail_host, 465) # 發件人郵箱中的SMTP服務器,端口是465smtpObj.login(mail_user, mail_pass)smtpObj.sendmail(sender, receivers, msgRoot.as_string())print("郵件發送成功") except smtplib.SMTPException:print("Error: 無法發送郵件")2.1.4添加附件發送帶附件的郵件,首先要創建MIMEMultipart()實例,然后構造附件,如果有多個附件,可依次構造,最后利用smtplib.smtp發送。
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.header import Header sender = '**********@qq.com' receivers = ['**********@qq.com'] # 接收郵件,可設置為你的QQ郵箱或者其他郵箱 #創建一個帶附件的實例 message = MIMEMultipart() message['From'] = Header("Python SMTP教程", 'utf-8') message['To'] = Header("測試", 'utf-8') subject = 'Python SMTP 郵件測試' message['Subject'] = Header(subject, 'utf-8') #郵件正文內容 message.attach(MIMEText('這是Python 郵件發送測試……', 'plain', 'utf-8')) # 構造附件1,傳送當前目錄下的 test.txt 文件 att_annex1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8') att_annex1["Content-Type"] = 'application/octet-stream' # 這里的filename可以任意寫,寫什么名字,郵件中顯示什么名字 att_annex1["Content-Disposition"] = 'attachment; filename="test.txt"' message.attach(att_annex1) # 構造附件2,傳送當前目錄下的 test2.txt 文件 att_annex2 = MIMEText(open('test2.txt', 'rb').read(), 'base64', 'utf-8') att_annex2["Content-Type"] = 'application/octet-stream' att_annex2["Content-Disposition"] = 'attachment; filename="test_file.txt"' message.attach(att_annex2) try:smtpObj = smtplib.SMTP('localhost')smtpObj.sendmail(sender, receivers, message.as_string())print "郵件發送成功" except smtplib.SMTPException:print "Error: 無法發送郵件"2.3 multpart說明
常見的multipart類型有三種:multipart/alternative, multipart/related和multipart/mixed。
郵件類型為"multipart/alternative"的郵件包括純文本正文(text/plain)和超文本正文(text/html)。
郵件類型為"multipart/related"的郵件正文中包括圖片,聲音等內嵌資源。
郵件類型為"multipart/mixed"的郵件包含附件。向上兼容,如果一個郵件有純文本正文,超文本正文,內嵌資源,附件,則選擇mixed類型。
msg = MIMEMultipart('mixed')我們必須把Subject,From,To,Date添加到MIMEText對象或者MIMEMultipart對象中,郵件中才會顯示主題,發件人,收件人,時間(若無時間,就默認一般為當前時間,該值一般不設置)。
msg = MIMEMultipart('mixed') msg['Subject'] = 'Python email test' msg['From'] = 'XXX@qq.com <XXX@qq.com>' msg['To'] = 'XXX@qq.com' msg['Date']='2020-10-16'查看MIMEMultipart屬性:
msg = MIMEMultipart('mixed') print dir(msg)結果:
['contains', 'delitem', 'doc', 'getitem', 'init', 'len', 'module', 'setitem', 'str', '_charset', '_default_type', '_get_params_preserve', '_headers', '_payload', '_unixfrom', 'add_header', 'as_string', 'attach', 'defects', 'del_param', 'epilogue', 'get', 'get_all', 'get_boundary', 'get_charset', 'get_charsets', 'get_content_charset', 'get_content_maintype', 'get_content_subtype', 'get_content_type', 'get_default_type', 'get_filename', 'get_param', 'get_params', 'get_payload', 'get_unixfrom', 'has_key', 'is_multipart', 'items', 'keys', 'preamble', 'replace_header', 'set_boundary', 'set_charset', 'set_default_type', 'set_param', 'set_payload', 'set_type', 'set_unixfrom', 'values', 'walk']
說明:
msg.add_header(_name,_value,**_params):添加郵件頭字段。
msg.as_string():是將msg(MIMEText對象或者MIMEMultipart對象)變為str,
如果只有一個html超文本正文或者plain普通文本正文的話,一般msg的類型可以是MIMEText;
如果是多個的話,就都添加到MIMEMultipart,msg類型就變為MIMEMultipart。
msg.attach(MIMEText對象或MIMEImage對象):
? 將MIMEText對象或MIMEImage對象添加到MIMEMultipart對象中。
? MIMEMultipart對象代表郵件本身,MIMEText對象或MIMEImage對象代表郵件正文。
以上的構造的文本,超文本,附件,圖片都可以添加到MIMEMultipart('mixed')中:
msg.attach(text_plain) msg.attach(text_html) msg.attach(text_att) msg.attach(image)附加案例:
文字,html,圖片,附件實現案例:
# 發送郵件 import smtplib from email.mime.text import MIMEText from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.header import Header import os# 設置smtplib所需的參數 # 下面的發件人,收件人是用于郵件傳輸的。 HOST = "smtp.qq.com" # smtp服務器地址 PORT = '465' # smtp服務器端口號 from_addr = "********@qq.com" # 發送郵件的賬號 qqCode = "famakkldfsbjag" # 登陸授權碼 to_addr = ["*******@qq.com"] # 接收郵件的賬號 這里可以是一個列表,多個收件郵箱# 構造郵件對象MIMEMultipart對象 # 下面的主題,發件人,收件人,日期是顯示在郵件頁面上的。 message = MIMEMultipart('mixed') subject = 'Python SMTP 郵件測試' # 郵件主題/標題 message['Subject'] = Header(subject, 'utf-8') # 通過Header對象編碼的文本,包含utf-8編碼信息和Base64編碼信息 message['From'] = Header(from_addr, 'utf-8') # 括號里的對應發件人郵箱昵稱(隨便起)、發件人郵箱賬號 message['To'] = Header(';'.join(to_addr), 'utf-8') # 收件人為多個收件人,通過join將列表轉換為以;為間隔的字符串 # message['To'] = Header(to_addr, 'utf-8') # 括號里的對應收件人郵箱昵稱、收件人郵箱賬號# 構造文字內容 msg_text = """ Hi! How are you? Here is the link you wanted: https://www.zhihu.com/ """ text_file_path = "test1.txt"def msg_text_attach(plain_text):"""讀取文件或者使用變量傳遞純文本"""if os.path.isfile(plain_text):"""如果傳遞的是路徑,則讀取文本"""with open(plain_text, 'rb') as text_file:plain_text = text_file.read()msg_text_plain = MIMEText(plain_text, 'plain', 'utf8')message.attach(msg_text_plain)msg_text_attach(msg_text)# 構造HTML內容 html_content = """<html> <head></head> <body> <p>Python 郵件發送測試...<br> How are you?<br> Here is the <a href="http://www.zhihu.com/people/4k8k">link</a> you wanted.<br> </p> </body> </html> """def html_text_attach(html_text):"""不需要做替換掉 html構造"""html_msg = MIMEText(html_text, 'html', 'utf-8')message.attach(html_msg)# html_text_attach(html_content)def msg_text_html_attach(html_text_file):"""構造一個需要替換圖片的html"""msg_alternative = MIMEMultipart('alternative')message.attach(msg_alternative)try:with open(html_text_file, 'r', encoding='utf8') as html_file:html_text_content = html_file.read()except Exception as eh:print('未找到html文件', eh)msg_alternative.attach(MIMEText(html_text_content, 'html', 'utf8'))def add_image(image_path, cid):# 指定圖片為當前目錄with open(image_path, 'rb') as image_file:msg_image = MIMEImage(image_file.read())# 定義圖片id,在html文本中引用msg_image.add_header('Content-ID', cid)message.attach(msg_image)# 使用字典保存HTML文件路徑 html_file_path = {"html1": "使用教程.html","html2": "test_send.html" }image_paths = {"image1": "./image/主圖1.jpg","image2": "./image/主圖2.jpg","image3": "./image/主圖3.jpg","image4": "./image/場景.jpg" }image_cids = {"image1": "jpg1","image2": "jpg2","image3": "jpg3","image4": "jpg4"}msg_text_html_attach(html_file_path.get("html2")) add_image(image_paths.get('image1'), image_cids.get('image1')) # 替換cid1 add_image(image_paths.get('image2'), image_cids.get('image2')) # 替換cid2 add_image(image_paths.get('image3'), image_cids.get('image3')) # 替換cid3 add_image(image_paths.get('image4'), image_cids.get('image4')) # 替換cid4""" html2即 test_send.html內容如下 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Send mail Tets</title> </head> <body> <img src="cid:jpg1" width="400" height="400" alt=""> <br><br> <img src="cid:jpg2" width="400" height="400" alt=""> <br><br> <img src="cid:jpg3" width="400" height="400" alt=""> <br><br> <img src="cid:jpg4" width="400" height="400" alt=""> </body> </html>"""# 構造圖片鏈接def image_attach(image_file_path, imgid, filename=None):if filename is None:"""如果不重命名文件,則默認使用源文件名"""filename = image_file_pathtry:with open(image_file_path, 'rb') as image_file:image_content = image_file.read()except Exception as ei:print('未找到圖片文件', ei)image = MIMEImage(image_content)image.add_header('Content-ID', imgid) # image1是照片別名,可以在HTML代碼中引用image['Content-Disposition'] = f'attachment; filename={filename}'message.attach(image)image_attach('test.jpg', 'image1', 'test_image.jpg')# 構造附件def send_annex_file(annex_file_path, annex_filename=None):"""傳入附加文件路徑和文件名(重命名附件,可以省略,默認為源文件名)"""if annex_filename is None:annex_filename = annex_file_pathtry:with open(annex_file_path, 'rb') as annex_file:send_file = annex_file.read()except Exception as es:print('未找到附件', es)text_appendix = MIMEText(send_file, 'base64', 'utf-8')text_appendix["Content-Type"] = 'application/octet-stream'# 以下附件可以重命名成:核心數據.xlsx# text_appendix["Content-Disposition"] = 'attachment; filename="核心數據.xlsx"'# 另一種附件重命名實現方式text_appendix.add_header('Content-Disposition', 'attachment', filename=annex_filename)message.attach(text_appendix)# 使用字典保存文件路徑 annex_path = {"file1": "核心數據.xlsx","file2": "test1.txt","file3": "使用教程.html" } send_annex_file(annex_path["file1"], '核心數據報表.xlsx') send_annex_file(annex_path["file2"]) send_annex_file(annex_path.get('file3'))""" 郵件類型為"multipart/alternative"的郵件包括純文本正文(text/plain) 和超文本正文(text/html)。 郵件類型為"multipart/related"的郵件正文中包括圖片,聲音等內嵌資源。 郵件類型為"multipart/mixed"的郵件包含附件。向上兼容, 如果一個郵件有純文本正文,超文本正文,內嵌資源,附件,則選擇mixed類型。 """# 配置服務器 發送郵件 try:# 配置服務器# smtp = smtplib.SMTP() # 1 創建SMTP實例# smtp.connect('smtp.qq.com', PORT) # 2 連接SMTP服務器server = smtplib.SMTP_SSL(HOST, PORT) # 本例這里直接一步到位# #打印出和SMTP服務器交互的所有信息# server.set_debuglevel(1) # python里打印出來的內容是紅色的,有點像報錯,這里屏蔽了,可以正常發郵件# 登錄SMTP服務器server.login(from_addr, qqCode)# 發送郵件,由于可以一次發給多個人,所以傳入一個list,郵件正文是一個str,as_string()把MIMEText對象變成strserver.sendmail(from_addr, to_addr, message.as_string())server.quit()print('--郵件發送成功--') except Exception as e:print('--郵件發送失敗--' + str(e))# 說明html和text純文本內容不能同時存在,html會覆蓋掉text純文本總結
以上是生活随笔為你收集整理的foxmail 怎么把邮件格式默认为html_Python SMTP发送邮件-smtplib模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 戴尔全新XPS 13 9315微边框笔记
- 下一篇: python自动控制库_Python最为