Python 邮件模块

python的邮件模块对于周期性邮件发送(如日报、周报)是非常高效的,搭配time库还能实现定时发送,搭配pandas、matplotlib可实现数据分析、可视化和报表发送的全流程自动化,对于工作效率提升有极高价值,本文简要介绍邮件模块的基本实现。

一、详细步骤

1.前提

  1. 设置邮箱的安全权限(设置为低)或者使用一个随机账号邮箱
  2. 设置gmail该页允许captcha,从而让python可以登录该gmail

2.载入库

smtplib(控制服务器通信)、mimetext(控制邮件的内容)、mimemultipart(控制邮件的样式和结构)

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
import smtplib 

3. 库的使用

smtplib

  1. 建立连接
    server = smtplib.SMTP(host='smtp.163.com', port=25)
    创建一个SMTP连接实例

国内邮箱port一般为25

  1. 向ESMTP服务器标识身份(可选)
    SMTP.ehlo(name='')
    该方法可选,一般可在在send_mail方法中调用,name默认为本地主机名。

若是SMTP服务器则使用helo()方法

  1. 设置SMTP的联结模式,默认为TLS(Transport Layer Security)
    SMTP.starttls(keyfile=None, certfile=None, context=None)
    使用后,所有smtp命令都会被编码
  2. 登陆
    SMTP.login(user, password, *, initial_response_ok=True)
  3. 发送邮件
    SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())
    发送邮件,必须要有收件人和发件人地址,和一个信息字符串。from_addr放一个邮箱,to_addrs放一个邮箱列表。

如果没有明确定义EHLOHELO,则会优先使用ESMP测试服务器

  1. 终止进程并关闭连接
    SMTP.quit()

MIMEMultipart

class email.mime.multipart.MIMEMultipart(_subtype=‘mixed’, boundary=None, _subparts=None, *, policy=compat32, **_params)

  1. _subtype
    子类型,控制结构,一共三种可选,见下图,默认为mixed
    [image:F03CCC37-27D0-4243-B4B5-54225B6F4231-1376-0000A5E6CF0A5887/FBCC8C1A-E79A-44F4-86AA-B1CE0D6ABA26.png]
    msg = MIMEMultipart('alternative')
  2. _subparts
    控制初始化的内容,可以通过attach添加,如先用mimetext创建了对象,再添加到mimemultipart对象后
      if html != 'None':
        html_part = MIMEText(html, 'html')
        msg.attach(html_part)

对于html,需要一个完整的html模块来实现,可参考前端的html格式,同时可以借助pd中的to_html函数将任何类型的数据转换成html然后以html放入邮件中

  1. _params
    是关键字参数,可以通过字典赋值,如果没有设置,则在发件人和收件人的显示上仅显示邮箱和内容,没有主题和发件人收件人名称
   msg = MIMEMultipart('alternative')
    msg['To'] = ', '.join(to_email)
    msg['Subject'] = subject
    msg['From'] = from_email

其他关键字
[image:FCE83CEA-6538-4487-921C-2373B2521D15-1376-0000A70D9B96B2D4/715A658B-00BC-4D1B-A352-54AC2EBD56D2.png]

MIMEText

class email.mime.text.MIMEText(_text, _subtype=‘plain’, _charset=None, *, policy=compat32)
_text即变量名,_subtype为子类型,可以是html、plain等

MIMEApplication

class email.mime.application.MIMEApplication(_data, _subtype=‘octet-stream’, _encoder=email.encoders.encode_base64, *, policy=compat32, **_params)
此处_data是 attachment.read()
如果要更换可以使用set_payload更换内容

MIMEBase(基类)

实现附件添加
class email.mime.base.MIMEBase(_maintype, _subtype, *, policy=compat32, **_params)

  1. _maintype
    主类型(内容),例如是文本还是图像
    [image:80F4AF5B-C960-405F-86EB-A1A03D6AF884-1376-0000AC0074BDF04C/7073B2C3-D0C8-4E1C-865D-1AEC6F2EDAE9.png]
    [image:1F93C5C6-4C7A-4713-870E-69FC02257BDE-1376-0000BC7E806EFCCF/39E37A0C-FE13-4D0B-A78F-1B6636DA4928.png]
    其中application是指主类型,x-zip-compressed是其一个子类型
    可写作:
    part = MIMEBase(‘application’, ‘x-zip-compressed’)——即zip文件类型

常见主类型、子类型
[image:682DEEFD-B943-4688-894C-52541E3B618D-1376-0000AC3BD9B3F004/A52C6262-EB06-43BD-AA96-226F89BBD7A5.png]

  1. _subtype
    子类型,例如文本的格式是plain,图像的格式是gif
  2. _params
    关键字参数,键值字典,可以通过add_header添加
    part.add_header('Content-Dispostition', 'attachment; file_name =%s%'file_name)
    添加一个附件
    file_name = os.path.basename(file_location)
    attachment = open(file_location, 'rb') # 创建对象
    part = MIMEBase('application', 'octet-stream')
    part.set_payload((attachment).read()) # 添加有效载重
    encoders.encode_base64(part)
    part.add_header('Content-Dispostition', 'attachment; file_name =%s%'file_name)
    msg.attach(part)

二、总结

  1. 文件路径导入os读取文件名→
  2. 读取文件路径并将读取文件内容存储到变量中→
  3. 创建一个MIMEBase对象(设置参数)→
  4. m对象加载刚刚存储的文件变量→
  5. 给m对象添加参数告诉它要把文件以何名放在何处→
  6. 将m对象添加到multipart对象中去

对于不同的文件一定要选择不同的主类型和子类型,否则传输过程中会出错导致最终结果有误;另外如果要添加附件,参数一定要换成mixed

附:源码

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import os.path

username = 'finnli1991@163.com'
password = 'UTRKSWKDNSHJGSFO'


def send_mail(
        text='Email Body', subject='Hello world',
        from_email='Finn li <finnli1991@163.com>',
        to_email=None, html=None, file_location=None):
    assert isinstance(to_email, list)
    msg = MIMEMultipart('alternative')
    msg['To'] = ', '.join(to_email)
    msg['Subject'] = subject
    msg['From'] = from_email
    txt_part = MIMEText(text, 'plain')
    msg.attach(txt_part)
    if html != 'None':
        html_part = MIMEText(html, 'html')
        msg.attach(html_part)
    msg_str = msg.as_string()

    file_name = os.path.basename(file_location)
    attachment = open(file_location, 'rb')
    # 创建对象
    part = MIMEBase('application', 'octet-stream')
    # 添加有效载重
    part.set_payload((attachment).read())
    encoders.encode_base64(part)
    part.add_header('Content-Dispostition', 'attachment; file_name =%s%'file_name)
    msg.attach(part)

    # 登录smtp服务器
    server = smtplib.SMTP(host='smtp.163.com', port=25)
    server.ehlo()
    server.starttls()
    server.login(username, password)
    server.sendmail(from_email, to_email, msg_str)
    server.quit()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342