小白入門(mén)者疤,用python 發(fā)送定時(shí)郵件福澡,將Dataframe轉(zhuǎn)為郵件正文,鏈接顯示為圖片

在實(shí)際工作中驹马,我們常常會(huì)遇到定時(shí)發(fā)送郵件的任務(wù)革砸,基于我的實(shí)踐,分享給大家糯累,也許一篇文章寫(xiě)不完算利,就先列個(gè)目錄。

本文想要解決的問(wèn)題:

  1. 用python構(gòu)造一封郵件泳姐,并設(shè)置定時(shí)發(fā)送出去效拭。往往,這只是最低級(jí)的需求胖秒,實(shí)際工作中會(huì)有各種細(xì)節(jié)和附加條件缎患。
  2. 學(xué)會(huì)構(gòu)造文本、HTML兩種格式的郵件正文阎肝,學(xué)會(huì)構(gòu)造和添加附件挤渔,其中,HTML格式要學(xué)會(huì)使用超鏈接风题,學(xué)會(huì)添加CSS用來(lái)美化正文判导。
  3. 將Dataframe格式的表格直接轉(zhuǎn)化為HTML格式的表格,如果有超鏈接俯邓,要學(xué)會(huì)更改超鏈接骡楼,使之能完全顯示熔号,并在HTML正文顯示對(duì)應(yīng)的連接內(nèi)容(比如顯示連接的圖片)稽鞭。

1. 初步學(xué)會(huì)使用python編寫(xiě)發(fā)送郵件的腳本

關(guān)于python發(fā)郵件的類(lèi)似文章有很多,不過(guò)引镊,作為初學(xué)者朦蕴,依然有許多需要注意的細(xì)節(jié)篮条,如果作者沒(méi)有寫(xiě)清楚的話,是很容易讓人抓狂的吩抓。
由于2020年官方就停止更新和支持python2涉茧,所以本文順應(yīng)大勢(shì),使用的python3.6

1. python庫(kù)
  • email庫(kù)疹娶,用來(lái)編輯郵件內(nèi)容的伴栓,包括標(biāo)題,發(fā)件人雨饺,接收人钳垮,正文等。
  • smtplib庫(kù)额港,用來(lái)發(fā)送郵件的饺窿,包括創(chuàng)建郵件服務(wù),登陸移斩,發(fā)送肚医,退出等動(dòng)作
    一般來(lái)說(shuō),我是做如下導(dǎo)入向瓷,每一個(gè)模塊都有相應(yīng)的說(shuō)明肠套,具體應(yīng)用繼續(xù)看后面的內(nèi)容。
# 導(dǎo)入相關(guān)庫(kù)-email
from email.mime.multipart import MIMEMultipart  # 構(gòu)建郵件頭信息猖任,包括發(fā)件人糠排,接收人,標(biāo)題等
from email.mime.text import MIMEText  # 構(gòu)建郵件正文超升,可以是text入宦,也可以是HTML
from email.mime.application import MIMEApplication  # 構(gòu)建郵件附件,理論上室琢,只要是文件即可乾闰,一般是圖片,Excel表格盈滴,word文件等
from email.header import Header  # 專門(mén)構(gòu)建郵件標(biāo)題的涯肩,這樣做,可以支持標(biāo)題中文

import smtplib
2. 發(fā)送一個(gè)最簡(jiǎn)單的hello word的郵件(有重點(diǎn))
  • 發(fā)件人信息(重點(diǎn))
    這一小節(jié)的重點(diǎn)巢钓,也是很多小白容易犯糊涂的地方病苗,就是發(fā)件人的賬號(hào)和密碼,以及相應(yīng)的郵件服務(wù)器設(shè)置症汹。不同的郵箱硫朦,其規(guī)則完全不一樣,如果你有企業(yè)郵箱背镇,那最好用企業(yè)郵箱咬展,這點(diǎn)要記住泽裳,因?yàn)閭€(gè)人郵箱很容易出現(xiàn)網(wǎng)絡(luò)問(wèn)題、觸發(fā)反垃圾機(jī)制等等破婆,這是實(shí)踐的出來(lái)的經(jīng)驗(yàn)涮总。另外,如果你使用過(guò)Foxmail祷舀、outlook等第三方郵件服務(wù)器瀑梗,那你就更容易理解了。
    上面箭頭所指裳扯,就是163個(gè)人郵箱的發(fā)件服務(wù)器

    上面箭頭所指夺克,就是163個(gè)人郵箱的發(fā)件服務(wù)器:smtp.163.com,如果是163的企業(yè)郵箱嚎朽,其服務(wù)器地址則是:smtp.ym.163.com铺纽,我就是用的這個(gè)。
    下面我要將的內(nèi)容很關(guān)鍵:163個(gè)人郵箱的密碼哟忍,不是登陸密碼狡门,而是客戶端授權(quán)碼,如下圖所示:
    image.png

    我們這里是屬于使用SMTP服務(wù)登陸和發(fā)送郵件的锅很,所以使用常規(guī)的登陸密碼其馏,是無(wú)法發(fā)送郵件的。
    然而爆安,163的企業(yè)郵箱叛复,卻沒(méi)有這個(gè)選項(xiàng),直接使用登陸密碼就可以發(fā)送郵件(我一直沒(méi)明白為什么不一樣扔仓,也許企業(yè)郵箱默認(rèn)的就是開(kāi)通了這些服務(wù)的褐奥,給我們的密碼也即是授權(quán)碼)。
    常見(jiàn)的qq郵箱翘簇,谷歌郵箱撬码,雅虎郵箱都是有這些區(qū)別的,新手一定要注意版保。下面就是我發(fā)送郵件的賬號(hào)的密碼設(shè)置呜笑,大家可以參照一下,不懂的直接在評(píng)論區(qū)@我:
    # 郵件服務(wù)信息彻犁,個(gè)人
    # smtp_server = 'smtp.163.com'
    # username = "lihua.0221@163.com"
    # password = 'xxxxxx'  # 授權(quán)碼叫胁,并不是郵箱登陸密碼

    # 郵件服務(wù)信息,公司
    smtp_server = 'smtp.ym.163.com'
    username = "lihua@everimaging.com"
    password = 'xxxxxxxxx'  # 授權(quán)碼汞幢,企業(yè)163的就是登陸密碼

這些信息驼鹅,我們?cè)跇?gòu)建郵件的發(fā)件人的時(shí)候需要用到,在使用SMTP發(fā)送郵件的時(shí)候也會(huì)用到,所以谤民,一開(kāi)始就給出來(lái)。

  • 構(gòu)建郵件正文
    # 郵件發(fā)送和接收人
    sender = username
    receiver = ['lihua@everimaging.com', '724694053@qq.com']

    # 郵件頭信息
    msg = MIMEMultipart('related')
    msg['Subject'] = Header("我的第一封python郵件")
    msg["From"] = sender
    msg['To'] = ','.join(receiver)  # 這里要注意

    # text 內(nèi)容
    content_text = MIMEText("Hello World", "text", "utf-8")
    msg.attach(content_text)

可以看到疾宏,這一節(jié)沒(méi)有什么難點(diǎn)张足,先是定義發(fā)送者和接收人,然后使用MIMEMultipart類(lèi)構(gòu)建一個(gè)消息體msg坎藐,然后定義msg中的主題为牍,發(fā)件人,接收人岩馍。其中碉咆,主題使用了Header類(lèi)封裝,目的是為了支持中文蛀恩,最后疫铜,添加一段text的正文“hello world”,使用的是MIMEText類(lèi)封裝双谆,第一個(gè)參數(shù)代表內(nèi)容壳咕,第二個(gè)參數(shù)代表類(lèi)型是text,另外還有html類(lèi)型可選顽馋,下節(jié)介紹谓厘,最后一個(gè)參數(shù)是定義編碼。
這里面只有一個(gè)地方需要注意寸谜,那就是msg['To'] = ','.join(receiver)這里竟稳,我們的郵件接收人是可以很多人的(列表),但是還需要用逗號(hào)把它們連接成一個(gè)字符串(email庫(kù)的bug)熊痴,如果是直接將列表扔給它他爸,是要出錯(cuò)的。

  • 發(fā)送郵件
    # 發(fā)送郵件果善,測(cè)試成功讲逛,流程都是固定的:創(chuàng)建客戶端,登陸岭埠,發(fā)送盏混,關(guān)閉
    email_client = smtplib.SMTP(smtp_server)
    email_client.login(username, password)
    email_client.sendmail(sender, receiver, msg.as_string())
    email_client.quit()

這段代碼,先是使用前面定義的郵件發(fā)送服務(wù)器:smtp_server = 'smtp.ym.163.com'來(lái)創(chuàng)建一個(gè)SMTP服務(wù)惜论,然后傳入賬號(hào)和密碼執(zhí)行登陸许赃,然后是發(fā)送郵件,需要的參數(shù)有:發(fā)送人馆类,接收人混聊,消息體,其中消息體執(zhí)行了as_string()乾巧,將整個(gè)msg對(duì)象轉(zhuǎn)化為了字符串句喜,最后是退出服務(wù)预愤。
這樣,我們的第一封郵件就發(fā)送成功了咳胃。下面是這一階段的完整代碼植康,我將自己賬號(hào)的password隱藏了,你只需要將你的賬號(hào)信息替換進(jìn)去展懈,執(zhí)行即可销睁,如果沒(méi)有成功,出現(xiàn)了任何不能解決的問(wèn)題存崖,請(qǐng)?jiān)谠u(píng)論區(qū)@我冻记。

# 導(dǎo)入相關(guān)庫(kù)-email
from email.mime.multipart import MIMEMultipart  # 構(gòu)建郵件頭信息,包括發(fā)件人来惧,接收人冗栗,標(biāo)題等
from email.mime.text import MIMEText  # 構(gòu)建郵件正文,可以是text供搀,也可以是HTML
from email.mime.application import MIMEApplication  # 構(gòu)建郵件附件贞瞒,理論上,只要是文件即可趁曼,一般是圖片军浆,Excel表格,word文件等
from email.header import Header  # 專門(mén)構(gòu)建郵件標(biāo)題的挡闰,這樣做乒融,可以支持標(biāo)題中文

import smtplib

def send_email():
    """發(fā)送郵件的腳本"""
    # 郵件服務(wù)信息,個(gè)人
    # smtp_server = 'smtp.163.com'
    # username = "lihua.0221@163.com"
    # password = 'xxxxx'  # 授權(quán)碼摄悯,并不是郵箱登陸密碼

    # 郵件服務(wù)信息赞季,公司
    smtp_server = 'smtp.ym.163.com'
    username = "lihua@everimaging.com"
    password = 'xxxxx'  # 授權(quán)碼,企業(yè)163的就是登陸密碼

    # 郵件發(fā)送和接收人
    sender = username
    receiver = ['lihua@everimaging.com', '724694053@qq.com']

    # 郵件頭信息
    msg = MIMEMultipart('related')
    msg['Subject'] = Header("我的第一封python郵件")
    msg["From"] = sender
    msg['To'] = ','.join(receiver)  # 這里要注意

    # text 內(nèi)容
    content_text = MIMEText("Hello World", "text", "utf-8")
    msg.attach(content_text)

    # 發(fā)送郵件奢驯,測(cè)試成功申钩,流程都是固定的:創(chuàng)建客戶端,登陸瘪阁,發(fā)送撒遣,關(guān)閉
    email_client = smtplib.SMTP(smtp_server)
    email_client.login(username, password)
    email_client.sendmail(sender, receiver, msg.as_string())
    email_client.quit()

if __name__ == '__main__':
    send_email()

2. 學(xué)會(huì)構(gòu)建HTML格式的正文,添加附件

前面我們已經(jīng)學(xué)會(huì)了基本的郵件發(fā)送腳本編寫(xiě)管跺,正文使用的是text义黎,但是,我們常見(jiàn)的郵件基本都是以HTML格式作為正文的豁跑,偶爾還會(huì)帶上一些附件廉涕。

  • HTML
    HTML就是網(wǎng)頁(yè),使用這種格式的正文,可以使我們的郵件內(nèi)容變得豐富無(wú)比狐蜕,理論上宠纯,網(wǎng)頁(yè)可以做成什么樣,我們HTML格式的郵件正文就可以做成什么樣2闶汀婆瓜!
    比如,我有下面這樣一個(gè)網(wǎng)頁(yè):
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>這是一封python寫(xiě)的郵件湃累,使用的是HTML格式構(gòu)造正文</h1>
<h2>可以為文字添加超鏈接勃救,比如:<a href="http://www.reibang.com/u/8159970c6959">簡(jiǎn)書(shū)-小溏</a></h2>
<hr>
<h3>還可以添加圖片碍讨,比如下面這張</h3>
<img src="https://pub-static.haozhaopian.net/assets/projects/export/jpg/29736970-a991-4b91-91af-854a8eb561e6.jpg">
</body>
</html>

在瀏覽器中顯示如下:


image.png

現(xiàn)在治力,我將它放進(jìn)我的郵件正文中,使用HTML格式勃黍,這種方式可以為文字添加超鏈接宵统,可以插入圖片

# 定義一個(gè)字符串,內(nèi)容就是HTML代碼
html_msg = \
    """
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>這是一封python寫(xiě)的郵件覆获,使用的是HTML格式構(gòu)造正文</h1>
    <h2>可以為文字添加超鏈接马澈,比如:<a href="http://www.reibang.com/u/8159970c6959">簡(jiǎn)書(shū)-小溏</a></h2>
    <hr>
    <h3>還可以添加圖片,比如下面這張</h3>
    <img src="https://pub-static.haozhaopian.net/assets/projects/export/jpg/29736970-a991-4b91-91af-854a8eb561e6.jpg">
    </body>
    </html>
    """

# html 內(nèi)容
content_html = MIMEText(html_msg, "html", "utf-8")
msg.attach(content_html)

我們定義好HTML字符串弄息,然后使用MIMEText類(lèi)封裝它痊班,第二個(gè)參數(shù)寫(xiě)“html”,同樣添加(attach)到msg對(duì)象中摹量。這和我們前面添加“hello word”這種純text的內(nèi)容方式是一樣的涤伐,如果你現(xiàn)在還不明白上面這段代碼該放在哪個(gè)位置,稍后我會(huì)給出完整的代碼缨称。

  • 添加附件
    關(guān)于附件凝果,有2個(gè)問(wèn)題需要重視:
    1. 附件的路徑,最好是使用全路徑睦尽。
    1. 附件的中文名稱器净,需要設(shè)置編碼。
      添加附件前当凡,我們需要確定附件的位置山害,也就是在系統(tǒng)上的路徑。關(guān)于路徑沿量,我是吃過(guò)大虧的粗恢,所以各位新手也要注意,在不同的系統(tǒng)(linux和windows)是不一樣的路徑欧瘪,分隔符也有區(qū)別眷射,特別是要定時(shí)跑的腳本,在linux系統(tǒng)中的不同位置運(yùn)行該腳本,相對(duì)路徑都不一樣妖碉,稍不注意就會(huì)break掉涌庭。

假如我要添加的附件是下面這個(gè):

excel_file_path = r'E:\WorkSpace\pythonProjects\Ontime_Script\attach_table\recurring_pay_failed_user_info_2018-05-09.xlsx'

我寫(xiě)的是windows下的全路徑,分隔符使用的是單個(gè)的正斜杠欧宜,前面加了個(gè)r坐榆,可以使那種類(lèi)似轉(zhuǎn)義符的代碼失效。
如果是Linux下冗茸,該是這樣的:

excel_file_path  = '/root/pythonProjects/Ontime_Script/attach_table/recurring_pay_failed_user_info_2018-05-09.xlsx'

寫(xiě)成全路徑席镀,無(wú)論是在哪個(gè)目錄下運(yùn)行該腳本,都不會(huì)出現(xiàn)錯(cuò)誤夏漱,這點(diǎn)要注意豪诲,相對(duì)路徑是很坑人的。

# 構(gòu)造附件挂绰,測(cè)試成功屎篱,附件有很多類(lèi)型,現(xiàn)在構(gòu)建的是html文件
attach_table = MIMEApplication(open(excel_file_path, 'rb').read())
# 給附件增加標(biāo)題
attach_table.add_header('Content-Disposition', 'attachment',filename='我的附件.xlsx')
#  這樣的話葵蒂,附件名稱就可以是中文的了交播,不會(huì)出現(xiàn)亂碼
attach_table.set_charset('utf-8')
msg.attach(attach_table)

上面就是為msg對(duì)象添加附件的全過(guò)程了:先將xlsx文件讀成二進(jìn)制,作為參數(shù)構(gòu)造MIMEApplication類(lèi)践付,第二步是為這個(gè)附件添加名稱(這個(gè)名稱是在郵件中顯示的)秦士,如果是中文,還需要設(shè)置一下編碼永高,否則中文會(huì)顯示為亂碼隧土,最后添加到msg中。
下面就是此節(jié)的全部代碼:

# 導(dǎo)入相關(guān)庫(kù)-email
from email.mime.multipart import MIMEMultipart  # 構(gòu)建郵件頭信息乏梁,包括發(fā)件人次洼,接收人,標(biāo)題等
from email.mime.text import MIMEText  # 構(gòu)建郵件正文遇骑,可以是text卖毁,也可以是HTML
from email.mime.application import MIMEApplication  # 構(gòu)建郵件附件,理論上落萎,只要是文件即可亥啦,一般是圖片,Excel表格练链,word文件等
from email.header import Header  # 專門(mén)構(gòu)建郵件標(biāo)題的翔脱,這樣做,可以支持標(biāo)題中文

import smtplib

def send_email(html_msg):
    """發(fā)送郵件的腳本"""
    # 郵件服務(wù)信息媒鼓,個(gè)人
    # smtp_server = 'smtp.163.com'
    # username = "lihua.0221@163.com"
    # password = 'xxxxx'  # 授權(quán)碼届吁,并不是郵箱登陸密碼

    # 郵件服務(wù)信息错妖,公司
    smtp_server = 'smtp.ym.163.com'
    username = "lihua@everimaging.com"
    password = 'xxxxxx'  # 授權(quán)碼,企業(yè)163的就是登陸密碼

    # 郵件發(fā)送和接收人
    sender = username
    receiver = ['lihua@everimaging.com', '724694053@qq.com']

    # 郵件頭信息
    msg = MIMEMultipart('related')
    msg['Subject'] = Header("我的第一封python郵件")
    msg["From"] = sender
    msg['To'] = ','.join(receiver)  # 這里要注意

    html_msg = \
        """
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
        <h1>這是一封python寫(xiě)的郵件疚沐,使用的是HTML格式構(gòu)造正文</h1>
        <h2>可以為文字添加超鏈接暂氯,比如:<a href="http://www.reibang.com/u/8159970c6959">簡(jiǎn)書(shū)-小溏</a></h2>
        <hr>
        <h3>還可以添加圖片,比如下面這張</h3>
        <img src="https://pub-static.haozhaopian.net/assets/projects/export/jpg/29736970-a991-4b91-91af-854a8eb561e6.jpg">
        </body>
        </html>
        """

    # html 內(nèi)容
    content_html = MIMEText(html_msg, "html", "utf-8")
    msg.attach(content_html)

    excel_file_path = r'E:\WorkSpace\pythonProjects\Ontime_Script\email_market_report\attach_table\recurring_pay_failed_user_info_2018-05-09.xlsx'
    # 構(gòu)造附件亮蛔,測(cè)試成功痴施,附件有很多類(lèi)型,現(xiàn)在構(gòu)建的是xlsx文件
    attach_table = MIMEApplication(open(excel_file_path, 'rb').read())
    # 給附件增加標(biāo)題
    attach_table.add_header('Content-Disposition', 'attachment',filename='我的附件.xlsx')
    #  這樣的話究流,附件名稱就可以是中文的了辣吃,不會(huì)出現(xiàn)亂碼
    attach_table.set_charset('utf-8')
    msg.attach(attach_table)

    # 發(fā)送郵件,測(cè)試成功芬探,流程都是固定的:創(chuàng)建客戶端神得,登陸,發(fā)送灯节,關(guān)閉
    email_client = smtplib.SMTP(smtp_server)
    email_client.login(username, password)
    email_client.sendmail(sender, receiver, msg.as_string())
    email_client.quit()

if __name__ == '__main__':
    send_email()

如果你需要添加其他類(lèi)型的附件循头,比如圖片绵估,word炎疆,壓縮包等,都是一樣的国裳,只是把文件名換一下即可形入,還有附件名稱的后綴。
學(xué)到此處缝左,基本的郵件發(fā)送是沒(méi)問(wèn)題了亿遂,但,往往實(shí)際工作中沒(méi)有這么簡(jiǎn)單渺杉,HTML代碼不是現(xiàn)成的蛇数,附件也需要臨時(shí)生成等等。

3. 將Dataframe轉(zhuǎn)為HTML是越,用CSS美化表格耳舅,設(shè)置URL,使之顯示完全等細(xì)節(jié)工作

定時(shí)郵件倚评,經(jīng)常會(huì)伴隨著實(shí)時(shí)數(shù)據(jù)的展現(xiàn)浦徊,在python中使用最多的是pandas包下面的DataFrame類(lèi),它就像一個(gè)Excel表格一樣天梧,可以完美的展示數(shù)據(jù)盔性,但是,我們?cè)撊绾螌⑺昝赖恼宫F(xiàn)在郵件的正文中呢呢岗?
現(xiàn)在我給出一個(gè)示例的表格數(shù)據(jù):
源數(shù)據(jù)鏈接:https://pan.baidu.com/s/1m9v3i153-M17Q8D6cmnMjw 密碼:k8pk

image.png

如果是直接將這個(gè)Excel文件作為附件發(fā)送到郵件里冕香,查看郵件的人是很苦惱的蛹尝,首先還要下載附件,打開(kāi)Excel悉尾,后面的縮略圖還只是URL箩言,想看具體長(zhǎng)什么樣,還得一個(gè)一個(gè)點(diǎn)開(kāi)在瀏覽器里面查看焕襟。
現(xiàn)在陨收,如果用HTML正文格式展示這個(gè)表格,上面講到的痛點(diǎn)都會(huì)解決鸵赖。
首先务漩,我們讀取Excel文件成為Dataframe格式

import pandas as pd

df = pd.read_excel(r"E:\WorkSpace\pythonProjects\Ontime_Script\attach_table\template_use.xlsx")

Dataframe有一個(gè)函數(shù)是to_html(),可以直接將df轉(zhuǎn)為HTML中的table它褪,它的參數(shù)相當(dāng)多

def to_html(self, buf=None, columns=None, col_space=None, header=True,
                index=True, na_rep='NaN', formatters=None, float_format=None,
                sparsify=None, index_names=True, justify=None, bold_rows=True,
                classes=None, escape=True, max_rows=None, max_cols=None,
                show_dimensions=False, notebook=False, decimal='.',
                border=None):

現(xiàn)在饵骨,我們先把df中的縮略圖包裝一下,以適應(yīng)HTML中顯示圖片的格式

df['縮略圖'] = '<img src="' + df['縮略圖'] + '">'

然后執(zhí)行轉(zhuǎn)換

df_html = df.to_html(escape=False)

escape這個(gè)參數(shù)是:Convert the characters <, >, and & to HTML-safe sequences.=
就是說(shuō)茫打,我們df里面居触,如果有HTML的特有元素,是轉(zhuǎn)化為轉(zhuǎn)義的呢老赤?還是保持本身的樣子不變轮洋。顯然,我們?cè)O(shè)置了img的格式抬旺,要在HTML中展示圖片弊予,比如下面這個(gè)

<img src="https://pub-static.haozhaopian.net/assets/projects/export/jpg/dd73de46-7b9b-45ca-b89b-651843304f59.jpg"> 

我們不希望將<這種符號(hào)變?yōu)?lt;,而是保持本身的樣子开财,所以將escape設(shè)置為False汉柒,(也許我沒(méi)有講清楚,不過(guò)你可以在實(shí)踐中設(shè)置為T(mén)rue责鳍,看看最終會(huì)發(fā)生什么碾褂,其實(shí),默認(rèn)的就是True)历葛。
現(xiàn)在正塌,我們的任務(wù)就是,構(gòu)造一個(gè)HTML的完整格式啃洋,然后將這個(gè)df_html 放進(jìn)去即可传货,對(duì)于HTML的美化,我也一并放在代碼中了宏娄,不在這里一一講解问裕。
本節(jié)全部的代碼:

import pandas as pd
# 導(dǎo)入相關(guān)庫(kù)-email
from email.mime.multipart import MIMEMultipart  # 構(gòu)建郵件頭信息,包括發(fā)件人孵坚,接收人粮宛,標(biāo)題等
from email.mime.text import MIMEText  # 構(gòu)建郵件正文窥淆,可以是text,也可以是HTML
from email.mime.application import MIMEApplication  # 構(gòu)建郵件附件巍杈,理論上忧饭,只要是文件即可,一般是圖片筷畦,Excel表格词裤,word文件等
from email.header import Header  # 專門(mén)構(gòu)建郵件標(biāo)題的,這樣做鳖宾,可以支持標(biāo)題中文

pd.set_option('display.max_colwidth', -1)  # 能顯示的最大寬度, 否則to_html出來(lái)的地址就不全

def get_html_msg():
    """
    1. 構(gòu)造html信息
    """
    df = pd.read_excel(r"E:\WorkSpace\pythonProjects\Ontime_Script\email_market_report\attach_table\template_use.xlsx")
    df['縮略圖'] = '<img src="' + df['縮略圖'] + '">'
    df_html = df.to_html(escape=False)

    head = \
        """
        <head>
            <meta charset="utf-8">
            <STYLE TYPE="text/css" MEDIA=screen>

                table.dataframe {
                    border-collapse: collapse;
                    border: 2px solid #a19da2;
                    /*居中顯示整個(gè)表格*/
                    margin: auto;
                }

                table.dataframe thead {
                    border: 2px solid #91c6e1;
                    background: #f1f1f1;
                    padding: 10px 10px 10px 10px;
                    color: #333333;
                }

                table.dataframe tbody {
                    border: 2px solid #91c6e1;
                    padding: 10px 10px 10px 10px;
                }

                table.dataframe tr {

                }

                table.dataframe th {
                    vertical-align: top;
                    font-size: 14px;
                    padding: 10px 10px 10px 10px;
                    color: #105de3;
                    font-family: arial;
                    text-align: center;
                }

                table.dataframe td {
                    text-align: center;
                    padding: 10px 10px 10px 10px;
                }

                body {
                    font-family: 宋體;
                }

                h1 {
                    color: #5db446
                }

                div.header h2 {
                    color: #0002e3;
                    font-family: 黑體;
                }

                div.content h2 {
                    text-align: center;
                    font-size: 28px;
                    text-shadow: 2px 2px 1px #de4040;
                    color: #fff;
                    font-weight: bold;
                    background-color: #008eb7;
                    line-height: 1.5;
                    margin: 20px 0;
                    box-shadow: 10px 10px 5px #888888;
                    border-radius: 5px;
                }

                h3 {
                    font-size: 22px;
                    background-color: rgba(0, 2, 227, 0.71);
                    text-shadow: 2px 2px 1px #de4040;
                    color: rgba(239, 241, 234, 0.99);
                    line-height: 1.5;
                }

                h4 {
                    color: #e10092;
                    font-family: 楷體;
                    font-size: 20px;
                    text-align: center;
                }

                td img {
                    /*width: 60px;*/
                    max-width: 300px;
                    max-height: 300px;
                }

            </STYLE>
        </head>
        """

    # 構(gòu)造模板的附件(100)
    body = \
        """
        <body>

        <div align="center" class="header">
            <!--標(biāo)題部分的信息-->
            <h1 align="center">我的python郵件吼砂,使用了Dataframe轉(zhuǎn)為table </h1>
        </div>

        <hr>

        <div class="content">
            <!--正文內(nèi)容-->
            <h2>帶圖片展示的表格</h2>

            <div>
                <h4></h4>
                {df_html}

            </div>
            <hr>

            <p style="text-align: center">
                —— 本次報(bào)告完 ——
            </p>
        </div>
        </body>
        """.format(df_html=df_html)
    html_msg= "<html>" + head + body + "</html>"
    # 這里是將HTML文件輸出,作為測(cè)試的時(shí)候鼎文,查看格式用的渔肩,正式腳本中可以注釋掉
    fout = open('t4.html', 'w', encoding='UTF-8', newline='')
    fout.write(html_msg)
    return html_msg

def send_data_df(html_msg):
    """發(fā)送郵件的腳本"""
    # 郵件服務(wù)信息,個(gè)人
    # smtp_server = 'smtp.163.com'
    # username = "lihua.0221@163.com"
    # password = 'xxxxxx'  # 授權(quán)碼拇惋,并不是郵箱登陸密碼

    # 郵件服務(wù)信息周偎,公司
    smtp_server = 'smtp.ym.163.com'
    username = "lihua@everimaging.com"
    password = 'xxxxxx'  # 授權(quán)碼,企業(yè)163的就是登陸密碼

    # 郵件發(fā)送和接收人
    sender = username
    receiver = ['lihua@everimaging.com', '724694053@qq.com']

    # 郵件頭信息
    msg = MIMEMultipart('related')
    msg['Subject'] = Header("我的第一封python郵件")
    msg["From"] = sender
    msg['To'] = ','.join(receiver)  # 這里要注意

    # html 內(nèi)容
    content_html = MIMEText(html_msg, "html", "utf-8")
    msg.attach(content_html)

    # 發(fā)送郵件撑帖,測(cè)試成功蓉坎,流程都是固定的:創(chuàng)建客戶端,登陸磷仰,發(fā)送袍嬉,關(guān)閉
    email_client = smtplib.SMTP(smtp_server)
    email_client.login(username, password)
    email_client.sendmail(sender, receiver, msg.as_string())
    email_client.quit()


if __name__ == '__main__':
    html_msg = get_html_msg()
    send_data(html_msg)

上面的代碼里境蔼,CSS占了很長(zhǎng)一段灶平,我沒(méi)有解釋,如果有任何問(wèn)題箍土,請(qǐng)聯(lián)系我逢享。
另外,這段代碼里還有一個(gè)很重要的
pd.set_option('display.max_colwidth', -1) # 能顯示的最大寬度, 否則to_html出來(lái)的地址就不全
這是設(shè)置Dataframe的顯示寬度的吴藻,因?yàn)榭s略圖那一列的內(nèi)容很長(zhǎng)瞒爬,如果沒(méi)有上訴設(shè)置的話,轉(zhuǎn)出來(lái)的地址就被省略了一部分沟堡,使得無(wú)法顯示圖片侧但,如果大家想測(cè)試其功能,可以注釋掉航罗,看看會(huì)發(fā)生什么結(jié)果禀横。最后,附上這個(gè)郵件的發(fā)送結(jié)果:


image.png

很漂亮有木有~~~~粥血,一眼就看到了圖片長(zhǎng)什么樣柏锄,還有跟它相關(guān)的信息在一起酿箭,也不用下載附件再點(diǎn)開(kāi)url了。
還有趾娃,如果大家想知道沒(méi)有CSS美化的結(jié)果是什么樣缭嫡,可以注釋掉CSS部分代碼,然后運(yùn)行看一看抬闷。
今天的分享就這樣了妇蛀,祝大家學(xué)習(xí)愉快。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笤成,一起剝皮案震驚了整個(gè)濱河市讥耗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疹启,老刑警劉巖古程,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異喊崖,居然都是意外死亡挣磨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)荤懂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)茁裙,“玉大人,你說(shuō)我怎么就攤上這事节仿∥钭叮” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵廊宪,是天一觀的道長(zhǎng)矾瘾。 經(jīng)常有香客問(wèn)我,道長(zhǎng)箭启,這世上最難降的妖魔是什么壕翩? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮傅寡,結(jié)果婚禮上放妈,老公的妹妹穿的比我還像新娘。我一直安慰自己荐操,他們只是感情好芜抒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著托启,像睡著了一般宅倒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上驾中,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天唉堪,我揣著相機(jī)與錄音模聋,去河邊找鬼。 笑死唠亚,一個(gè)胖子當(dāng)著我的面吹牛链方,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灶搜,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼祟蚀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了割卖?” 一聲冷哼從身側(cè)響起前酿,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鹏溯,沒(méi)想到半個(gè)月后罢维,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丙挽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年肺孵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颜阐。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡平窘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凳怨,到底是詐尸還是另有隱情瑰艘,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布肤舞,位于F島的核電站紫新,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏萨赁。R本人自食惡果不足惜弊琴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦顽染、人聲如沸盆耽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)化焕。三九已至,卻和暖如春铃剔,著一層夾襖步出監(jiān)牢的瞬間撒桨,已是汗流浹背查刻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凤类,地道東北人穗泵。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像谜疤,于是被迫代替她去往敵國(guó)和親佃延。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容