從古代的八百里加急,到現(xiàn)在的電子郵件,郵件的發(fā)展見(jiàn)證了上下五千年的發(fā)展史,這些當(dāng)然是廢話,只是要說(shuō)說(shuō)郵件的重要性??沙R?guī)的通信手段
可常規(guī)的通信手段相比,尤其是在現(xiàn)在,電話、QQ、微信等等各種社交軟件的興起,比傳統(tǒng)的郵件和現(xiàn)在的電子郵件都快捷了很多;那為什么電子郵件還是顯得那么重要呢~
電子郵件,目前來(lái)說(shuō)在不同的行業(yè)中還是占據(jù)著非常重要的辦公需求的地位的,常規(guī)情況下公司的任務(wù)分配、溝通、協(xié)作等等都是通過(guò)電子郵件進(jìn)行處理的;同時(shí),電子郵件本身的功能【郵件發(fā)送、群發(fā)、抄送、附件】讓它更加社和較為正式的辦公場(chǎng)合和日常較大數(shù)據(jù)的溝通;所以電子郵件的操作在各種編程語(yǔ)言中都有涉及和擴(kuò)展;也是我們必須掌握的技能之一
我們回顧一下傳統(tǒng)的郵件的發(fā)送過(guò)程(說(shuō)白了就是寫(xiě)信),寫(xiě)信的過(guò)程如下圖所示:
寫(xiě)好信件 -> 投遞到郵筒 -> 郵局?jǐn)埵账械泥]件 -> XX地區(qū)郵局 -> 傳送到XX地區(qū)郵局 -> 投遞 -> 個(gè)人郵筒 -> 看到信件
電子郵件的傳輸過(guò)程和傳統(tǒng)的模式有點(diǎn)類似,也是我們自己有寫(xiě)郵件的電子郵件軟件,寫(xiě)好的郵件點(diǎn)擊發(fā)送,發(fā)送到郵件服務(wù)器,某郵件服務(wù)器將郵件通過(guò)網(wǎng)絡(luò)傳送到另一個(gè)郵件服務(wù)器,郵件服務(wù)器將郵件投遞到目標(biāo)用戶的投遞服務(wù)區(qū),目標(biāo)用戶從投遞服務(wù)區(qū)收取郵件。
電子郵件發(fā)送流程及術(shù)語(yǔ)解釋
郵件發(fā)送處理過(guò)程:用戶A發(fā)送郵件給用戶B/C/D
術(shù)語(yǔ)解釋:
MUA:Mail User Agent,郵件用戶代理,我們可以簡(jiǎn)單的理解成我們使用的發(fā)送郵件的軟件,如Foxmail、outlook、gmail等等,這樣的軟件可以編輯郵件,發(fā)送/收取郵件
MTA:Mail Transfer Agent,郵件傳輸代理,我們通常情況下,注冊(cè)的郵箱都是屬于某一個(gè)運(yùn)營(yíng)商的,如xx@qq.com這是騰訊的郵箱、xx@163.com這是網(wǎng)易的郵箱等等,通常運(yùn)營(yíng)商會(huì)有自己的服務(wù)器專門用于郵件的網(wǎng)絡(luò)傳輸?shù)?,這里的MTA指代的就是運(yùn)營(yíng)商服務(wù)器
MDA:Mail Delivery Agent,郵件投遞代理,我們發(fā)送的郵件,會(huì)默認(rèn)保存在目標(biāo)服務(wù)器中的投遞服務(wù)區(qū),需要目標(biāo)用戶從投遞服務(wù)區(qū)中提取郵件(收取郵件)。
完成流程如下
郵件 -> MUA -> MTA -> ... n個(gè)MTA -> MDA <- MUA <- 郵件那我們程序中,如果要實(shí)現(xiàn)發(fā)送郵件和接收郵件的功能,就需要自己開(kāi)發(fā)程序完成從MUA-> MTA發(fā)送的過(guò)程來(lái)完成發(fā)郵件的功能;同樣需要完成從MUA->MDA收取郵件的過(guò)程完成收郵件的功能
smtp是發(fā)送郵件的一種常見(jiàn)的協(xié)議,python已經(jīng)內(nèi)置了smtp協(xié)議的支持,可以發(fā)送常規(guī)的郵件內(nèi)容(文本、附件、網(wǎng)頁(yè)等)
在郵件發(fā)送模塊中,主要使用如下兩個(gè)模塊進(jìn)行處理
接下來(lái),我們先了解一個(gè)簡(jiǎn)單的郵件發(fā)送程序
import email,smtplib
from email.mime.text import MIMEText
# 發(fā)送郵件服務(wù)器
smtp_server = "smtp.qq.com"
# 郵箱賬號(hào)+密碼
email_user = "xxxxxxxxx@qq.com"
email_pass = "qq用戶請(qǐng)?zhí)顚?xiě)授權(quán)碼"
# 發(fā)件人收件人信息
sender = email_user
receiver = "xxxxxx@xxxx.com"
# 發(fā)送的消息設(shè)置,plain表示文本,utf-8表示數(shù)據(jù)編碼格式
msg = MIMEText("這是一份自動(dòng)發(fā)送的測(cè)試郵件", "plain", "utf-8")
# 連接郵件服務(wù)器,用戶登錄, 發(fā)送郵件
server = smtplib.SMTP_SSL(smtp_server, 465)
server.set_debuglevel(1)
server.login(email_user, email_pass)
server.sendmail(sender, receiver, msg.as_string())
server.quit();
print("郵件發(fā)送結(jié)束")
上述代碼是通過(guò)qq郵箱發(fā)送郵件的案例
使用QQ郵箱發(fā)送郵件時(shí)需要注意,如果正常情況下,需要開(kāi)啟smtp等服務(wù),然后使用正確的登錄賬號(hào)和登錄密碼,如果一旦設(shè)置了QQ安全中心之類的,就需要通過(guò)設(shè)置授權(quán)碼進(jìn)行登錄打開(kāi)網(wǎng)頁(yè)版QQ郵箱,進(jìn)入[設(shè)置]選項(xiàng)->進(jìn)入[賬戶]選項(xiàng),操作如下內(nèi)容:
設(shè)置完上述內(nèi)容之后,運(yùn)行程序,我們?cè)谀繕?biāo)郵箱中就收到了對(duì)應(yīng)的郵件
上面的郵件我們已經(jīng)看出來(lái)了,在收件箱中看到的郵件,只是包含了發(fā)件人郵箱和郵件的文本內(nèi)容;郵件的標(biāo)題、發(fā)件人名稱、收件人名稱、郵件的格式等等都沒(méi)有進(jìn)行處理。
在python的email模塊中,可以通過(guò)設(shè)置Subject
設(shè)置郵箱標(biāo)題,設(shè)置From
設(shè)置發(fā)件人信息,設(shè)置To
設(shè)置收件人信息
通常情況下,我們會(huì)將標(biāo)題中的中文,使用email.header模塊中的Header()方法進(jìn)行編碼以保證數(shù)據(jù)傳輸?shù)恼_性;
在常規(guī)郵箱處理過(guò)程中,收件人和發(fā)件人這兩個(gè)信息的展示格式是類似于姓名
這樣的格式,這種格式在python中通過(guò)email.utils模塊中的parseaddr()
方法和formataddr()
方法進(jìn)行處理的
# 導(dǎo)入需要的模塊
import email, smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.utils import parseaddr, formataddr
# 定義連接郵箱服務(wù)器的信息
smtp_server = "smtp.qq.com"
smtp_user = "xxxxxxxx@qq.com"
smtp_pass = "qq用戶如果設(shè)置了安全策略的話這里要寫(xiě)授權(quán)碼"
# 設(shè)置發(fā)件人、收件人
sender = smtp_user
receiver = "xxxxxx@xxxx.com"
# 定義用于編碼發(fā)件人和收件人格式的方法
def _format_addr(user):
name, addr = parseaddr(user)
return formataddr((Header(name, "utf-8").encode(), addr))
# 開(kāi)始發(fā)送郵件
# 連接服務(wù)器
server = smtplib.SMTP_SSL(smtp_server, 465)
# 登錄服務(wù)器
server.login(smtp_user, smtp_pass)
# 設(shè)置內(nèi)容,標(biāo)題,發(fā)件人,收件人
msg = MIMEText("這是一個(gè)自動(dòng)發(fā)送的郵件", "plain", "utf-8")
msg["subject"] = Header("來(lái)自大牧莫邪的問(wèn)候")
msg["from"] = _format_addr("大牧莫邪 <%s>" % sender)
msg["to"] = _format_addr("牟文斌 <%s>" % receiver)
# 發(fā)送郵件
server.sendmail(sender, receiver, msg.as_string())
print("郵件發(fā)送成功")
可以看到,上面的代碼中,我們對(duì)標(biāo)題進(jìn)行了編碼設(shè)置,對(duì)發(fā)件人和收件人的格式進(jìn)行了處理;[注意:現(xiàn)在的郵箱服務(wù)器,某些情況下不通過(guò)Header編碼也可以正常識(shí)別中文,但是我們還是在代碼中進(jìn)行規(guī)范,防止出現(xiàn)中文亂碼的BUG]
正確接收郵件:
在上面的內(nèi)容中,我們已經(jīng)看到了,發(fā)送郵件的內(nèi)容,是通過(guò)MIMEText()函數(shù)進(jìn)行規(guī)范的,如果設(shè)置了plain
選項(xiàng)表示發(fā)送文本郵件,如果我們?cè)O(shè)置html
就是發(fā)送的HTML格式的郵件,HTML標(biāo)簽需要被解析出來(lái),請(qǐng)上干貨:
import email, smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.utils import parseaddr, formataddr
# 定義連接郵箱服務(wù)器的信息
smtp_server = "smtp.qq.com"
smtp_user = "1007821300@qq.com"
smtp_pass = "kyecgawxkkupbegh"
# 設(shè)置發(fā)件人、收件人
sender = smtp_user
receiver = "muwenbin@qikux.com"
# 設(shè)置對(duì)發(fā)件人、收件人格式化處理的方法
def _format_addr(user):
name, addr = parseaddr(user)
return formataddr((Header(name, "utf-8").encode(), addr))
# 設(shè)置連接郵箱服務(wù)器
server = smtplib.SMTP_SSL(smtp_server)
# 登錄賬號(hào)
server.login(smtp_user, smtp_pass)
# 設(shè)置郵箱標(biāo)題、發(fā)件人、收件人、內(nèi)容信息
msg = MIMEText("
Hello 你好
這是一封自動(dòng)發(fā)送的測(cè)試郵件", "html", "utf-8") msg["subject"] = Header("來(lái)自大牧莫邪的問(wèn)候") msg["from"] = _format_addr("大牧莫邪 <%s>" % sender) msg["to"] = _format_addr("木木 <%s>" % receiver) # 發(fā)送郵件 server.sendmail(sender, receiver, msg.as_string()) print("郵件發(fā)送完成")
郵件發(fā)送完成,收件箱中查看郵件
這里有人可能會(huì)有問(wèn)題,誰(shuí)TM沒(méi)事干,寫(xiě)一個(gè)郵件寫(xiě)那么多的HTML標(biāo)簽進(jìn)去呀,它瘋了?。?/p>
這里需要給大家普及一個(gè)前端的知識(shí)點(diǎn),我們通常在網(wǎng)頁(yè)中輸入內(nèi)容時(shí),會(huì)添加富文本編輯器,如百度的UEditor,富文本編輯器中會(huì)帶各種各樣的格式,這些格式底層其實(shí)就是HTML標(biāo)簽,我們將用戶在富文本編輯器中寫(xiě)的內(nèi)容進(jìn)行發(fā)送的時(shí)候,發(fā)送的就是HTML格式的文本數(shù)據(jù)
上面介紹了常規(guī)的郵件發(fā)送的處理手段,這里我們接著介紹一種非常常用的郵件內(nèi)容的處理方式:添加附件
添加了附件的郵件,我們就需要對(duì)郵件進(jìn)行拆分和組合的處理了。說(shuō)簡(jiǎn)單一點(diǎn)就是將郵件內(nèi)容和附件分別用對(duì)象表示,然后將不同的對(duì)象組合在一起作為一個(gè)完整的郵件即可
在python中,用MIMEText()服務(wù)類表示普通的郵件內(nèi)容,用MIMEBase()服務(wù)類來(lái)表示我們的附件對(duì)象,然后將郵件內(nèi)容和附件包裝在MIMEMultipart()中形成一個(gè)完整的郵件進(jìn)行發(fā)送
廢話少說(shuō),上干貨
# 導(dǎo)入需要的模塊
import email, smtplib
from email import encoders
from email.utils import parseaddr, formataddr
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 定義連接郵箱服務(wù)器的信息
smtp_server = "smtp.qq.com"
smtp_user = "xxxxxxxxx@qq.com"
smtp_pass = "qq用戶如果設(shè)置了安全驗(yàn)證,這里請(qǐng)?zhí)顚?xiě)您的授權(quán)碼"
# 設(shè)置發(fā)件人、收件人
sender = smtp_user
receiver = "xxxxxx@xxxx.com"
# 設(shè)置收件人,發(fā)件人格式的方法
def _format_addr(user):
name, addr = parseaddr(user)
return formataddr((Header(name, "utf-8").encode(), addr))
# 連接服務(wù)器
server = smtplib.SMTP_SSL(smtp_server)
# 登錄服務(wù)器
server.login(smtp_user, smtp_pass)
# 設(shè)置郵件內(nèi)容[可以包裝郵件內(nèi)容和附件的MIMEMultipart對(duì)象]
msg = MIMEMultipart()
msg["subject"] = Header("來(lái)自大牧的問(wèn)候", "utf-8")
msg["from"] = _format_addr("大牧來(lái)了 <%s>" % sender)
msg["to"] = _format_addr("牟文斌 <%s>" % receiver)
# 1.設(shè)置郵件正文內(nèi)容
content = MIMEText("這是郵件正文內(nèi)容部分", "plain", "utf-8")
# 將正文內(nèi)容添加到包裝對(duì)象中
msg.attach(content)
# 2.設(shè)置附件內(nèi)容<使用本地的圖片作為附件>
with open("d:/my.jpg", "rb") as f:
# 設(shè)置MIMEBase對(duì)象包裝附件
attachment = MIMEBase("image", "jpg", filename="header.jpg")
# 設(shè)置附件信息
attachment.add_header("Content-Disposition", "attachment", filename="header.jpg")
attachment.add_header("Content-ID", "<0>")
attachment.add_header("X-Attachment-Id", "0")
# 讀取附件內(nèi)容
attachment.set_payload(f.read())
# 編碼文件
encoders.encode_base64(attachment)
# 添加附件到包裝對(duì)象中
msg.attach(attachment)
# 發(fā)送郵件
server.sendmail(sender, receiver, msg.as_string())
print("郵件發(fā)送成功")
運(yùn)行上述程序之后,收件箱中,收到對(duì)應(yīng)的郵件內(nèi)容如下:
這里需要注意幾個(gè)問(wèn)題
- MIMEMultipart()對(duì)象也是一種郵件對(duì)象,可以包含多個(gè)組成部分
- MIMEText()對(duì)象主要用于進(jìn)行郵件正文內(nèi)容的設(shè)置,可以是純文本,可以是HTML格式
- MIMEBase()對(duì)象主要用于進(jìn)行附件的添加,常規(guī)情況下以獨(dú)立文件對(duì)象的形式作為郵件內(nèi)容的一部分而存在
完成的郵件格式是包含郵件正文內(nèi)容和附件的
MIMEMultipart()
對(duì)象
如果我們要在郵件中添加顯示的圖片應(yīng)該怎么做呢~
按照我們常規(guī)的理解,可以通過(guò)將郵件內(nèi)容修改為HTML,這樣的話,圖片就可以通過(guò)
標(biāo)簽插入進(jìn)入了,難道不是嗎?
郵件服務(wù)商們發(fā)現(xiàn)了一個(gè)問(wèn)題,如果在郵件中可以任意添加鏈接的話,很容易讓郵件作為一個(gè)犯罪的橋梁,把指向惡意網(wǎng)站或者服務(wù)的超鏈接帶入我們的PC,所以常規(guī)情況下,郵件中會(huì)自動(dòng)屏蔽帶外鏈接圖片的。
那應(yīng)該怎么做呢?
其實(shí)郵件中的圖片在python中處理的比較簡(jiǎn)單,郵件中需要的圖片,通過(guò)附件的形式上傳到郵件服務(wù)器,然后根據(jù)附件的順序使用cid:num
添加就可以了,語(yǔ)法類似![](cid:0)
這是在正文中使用附件中的第一個(gè)圖片
上干貨:
# 導(dǎo)入需要的模塊
import email, smtplib
from email import encoders
from email.utils import parseaddr, formataddr
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 定義連接郵箱服務(wù)器的信息
smtp_server = "smtp.qq.com"
smtp_user = "xxxxxxxxx@qq.com"
smtp_pass = "qq用戶如果設(shè)置了安全驗(yàn)證,這里請(qǐng)?zhí)顚?xiě)您的授權(quán)碼"
# 設(shè)置發(fā)件人、收件人
sender = smtp_user
receiver = "xxxxxx@xxxx.com"
# 設(shè)置收件人,發(fā)件人格式的方法
def _format_addr(user):
name, addr = parseaddr(user)
return formataddr((Header(name, "utf-8").encode(), addr))
# 連接服務(wù)器
server = smtplib.SMTP_SSL(smtp_server)
# 登錄服務(wù)器
server.login(smtp_user, smtp_pass)
# 設(shè)置郵件內(nèi)容[可以包裝郵件內(nèi)容和附件的MIMEMultipart對(duì)象]
msg = MIMEMultipart()
msg["subject"] = Header("來(lái)自大牧的問(wèn)候", "utf-8")
msg["from"] = _format_addr("大牧來(lái)了 <%s>" % sender)
msg["to"] = _format_addr("牟文斌 <%s>" % receiver)
# 1.設(shè)置郵件正文內(nèi)容
content = MIMEText("
這是郵件正文內(nèi)容部分
![](cid:0)", "html", "utf-8") # 將正文內(nèi)容添加到包裝對(duì)象中 msg.attach(content) # 2.設(shè)置附件內(nèi)容<使用本地的圖片作為附件> with open("d:/my.jpg", "rb") as f: # 設(shè)置MIMEBase對(duì)象包裝附件 attachment = MIMEBase("image", "jpg", filename="header.jpg") # 設(shè)置附件信息 attachment.add_header("Content-Disposition", "attachment", filename="header.jpg") attachment.add_header("Content-ID", "<0>") attachment.add_header("X-Attachment-Id", "0") # 讀取附件內(nèi)容 attachment.set_payload(f.read()) # 編碼文件 encoders.encode_base64(attachment) # 添加附件到包裝對(duì)象中 msg.attach(attachment) # 發(fā)送郵件 server.sendmail(sender, receiver, msg.as_string()) print("郵件發(fā)送成功")
上述代碼執(zhí)行完成后,在我們的收件箱中,赤果果個(gè)的就出現(xiàn)了下面的結(jié)果
溫情提示:以上代碼都是我使用QQ郵箱進(jìn)行測(cè)試過(guò)程中總結(jié)的資料,如果大家在使用其他郵箱進(jìn)行驗(yàn)證的過(guò)程中出現(xiàn)了問(wèn)題,歡迎留言一起討論哦!
| 郵箱|smtp服務(wù)器 |端口|
常用的郵箱服務(wù)器(SMTP、POP3)地址、端口
sina.com:
POP3服務(wù)器地址:pop3.sina.com.cn(端口:110)
SMTP服務(wù)器地址:smtp.sina.com.cn(端口:25)sinaVIP:
POP3服務(wù)器:pop3.vip.sina.com (端口:110)
SMTP服務(wù)器:smtp.vip.sina.com (端口:25)sohu.com:
POP3服務(wù)器地址:pop3.sohu.com(端口:110)
SMTP服務(wù)器地址:smtp.sohu.com(端口:25)126郵箱:
POP3服務(wù)器地址:pop.126.com(端口:110)
SMTP服務(wù)器地址:smtp.126.com(端口:25)139郵箱:
POP3服務(wù)器地址:POP.139.com(端口:110)
SMTP服務(wù)器地址:SMTP.139.com(端口:25)163.com:
POP3服務(wù)器地址:pop.163.com(端口:110)
SMTP服務(wù)器地址:smtp.163.com(端口:25)QQ郵箱
POP3服務(wù)器地址:pop.qq.com(端口:110)
SMTP服務(wù)器地址:smtp.qq.com (端口:25)QQ企業(yè)郵箱
POP3服務(wù)器地址:pop.exmail.qq.com (SSL啟用 端口:995)
SMTP服務(wù)器地址:smtp.exmail.qq.com(SSL啟用 端口:587/465)yahoo.com:
POP3服務(wù)器地址:pop.mail.yahoo.com
SMTP服務(wù)器地址:smtp.mail.yahoo.comyahoo.com.cn:
POP3服務(wù)器地址:pop.mail.yahoo.com.cn(端口:995)
SMTP服務(wù)器地址:smtp.mail.yahoo.com.cn(端口:587HotMail
POP3服務(wù)器地址:pop3.live.com (端口:995)
SMTP服務(wù)器地址:smtp.live.com (端口:587)gmail(google.com)
POP3服務(wù)器地址:pop.gmail.com(SSL啟用 端口:995)
SMTP服務(wù)器地址:smtp.gmail.com(SSL啟用 端口:587)263.net:
POP3服務(wù)器地址:pop3.263.net(端口:110)
SMTP服務(wù)器地址:smtp.263.net(端口:25)263.net.cn:
POP3服務(wù)器地址:pop.263.net.cn(端口:110)
SMTP服務(wù)器地址:smtp.263.net.cn(端口:25)x263.net:
POP3服務(wù)器地址:pop.x263.net(端口:110)
SMTP服務(wù)器地址:smtp.x263.net(端口:25)21cn.com:
POP3服務(wù)器地址:pop.21cn.com(端口:110)
SMTP服務(wù)器地址:smtp.21cn.com(端口:25)Foxmail:
POP3服務(wù)器地址:POP.foxmail.com(端口:110)
SMTP服務(wù)器地址:SMTP.foxmail.com(端口:25)china.com:
POP3服務(wù)器地址:pop.china.com(端口:110)
SMTP服務(wù)器地址:smtp.china.com(端口:25)tom.com:
POP3服務(wù)器地址:pop.tom.com(端口:110)
SMTP服務(wù)器地址:smtp.tom.com(端口:25)etang.com:
POP3服務(wù)器地址:pop.etang.com
SMTP服務(wù)器地址:smtp.etang.com
>>>更多VR/AR入門教程:VR入門
Python交流群
635448130點(diǎn)擊加入群聊UI設(shè)計(jì)交流群
579150876點(diǎn)擊加入群聊Unity交流群
495609038點(diǎn)擊加入群聊HTML5交流群
645591648點(diǎn)擊加入群聊