Python使用smtplib、zmail、yagmail发送邮件

本文为博主原创,未经许可严禁转载。
本文链接:https://blog.csdn.net/zyooooxie/article/details/113102263

之前分享过一期 smtplib发邮件踩过的坑;我感觉smtplib 用起来比较复杂,没那么好用,后来 我看到2个与发邮件相关的库 zmail、 yagmail,使用后有些心得,在此做个分享。

个人博客:https://blog.csdn.net/zyooooxie

需求

本篇主要是讲述 4个方法:

  1. 发送 内容为纯文本的邮件 send_text()
  2. 发送 内容为html格式的邮件 send_html()
  3. 发送 包含多个附件的邮件 send_file()
  4. 发送 混合的邮件 send_text_html_file()

代码

smtplib


def my_send_email(receiver: list, cc: list, msg):
    receiver.extend(cc)
	# 163邮箱
    # smtp = smtplib.SMTP()
    # smtp.connect(host=smtp_server, port=port)

	# qq邮箱
    smtp = smtplib.SMTP_SSL(host=smtp_server, port=port)

    smtp.login(user=sender, password=pwd)
    smtp.sendmail(from_addr=sender, to_addrs=receiver, msg=msg.as_string())
    smtp.quit()
    print('发送成功')


# text/plain(纯文本)
def send_text():
    receiver = '[email protected]'
    cc = '[email protected]'

    now_time = time.strftime('%Y%m%d_%H%M%S')
    random_int = random.randint(10000, 99999)
    print(now_time, random_int)

    subject = ':'.join(['smtplib-text', '重要邮件通知', '{} '.format(now_time), '随机码:{}'.format(random_int)])

    text = '1.邮件是由zyooooxie推送;\n2.{}完成测试'.format(faker.Faker(locale='zh_CN').name())

    msg = MIMEText(_text=text, _subtype='plain', _charset='utf-8')
    msg['from'] = sender
    msg['to'] = receiver
    msg['subject'] = subject
    msg['cc'] = cc

    my_send_email([receiver], [cc], msg)


# text/html(超文本)
def send_html():
    receiver = ['[email protected]', '[email protected]']
    cc = ['[email protected]', '[email protected]']

    now_time = time.strftime('%Y%m%d_%H%M%S')
    random_int = random.randint(10000, 99999)
    print(now_time, random_int)

    subject = ':'.join(['smtplib-html', '重要邮件通知', '{} '.format(now_time), '随机码:{}'.format(random_int)])

    body = """
    <p style="font-size:10px;color:red;line-height:90px">这由zyooooxie推送</p>
    <p style="font-size:30px;color:orange">{}完成测试</p>
    """.format(faker.Faker(locale='zh_CN').name())

    msg = MIMEText(_text=body, _subtype='html', _charset='utf-8')
    msg['from'] = sender
    msg['to'] = ','.join(receiver)
    msg['subject'] = subject
    msg['cc'] = ','.join(cc)

    my_send_email(receiver, cc, msg)


# 发送附件+正文添加图片
def send_file():
    receiver = '[email protected]'
    cc = ['[email protected]', '[email protected]']

    now_time = time.strftime('%Y%m%d_%H%M%S')
    random_int = random.randint(10000, 99999)
    print(now_time, random_int)

    subject = ':'.join(['smtplib-file', '重要邮件通知', '{} '.format(now_time), '随机码:{}'.format(random_int)])

    msg = MIMEMultipart('alternative')
    msg['from'] = sender
    msg['to'] = receiver
    msg['subject'] = subject
    msg['cc'] = ','.join(cc)

    file_path = r'D:\zy0'

    # 添加附件
    file_list = [i for i in os.listdir(file_path)]
    for fl in file_list:
        f = os.path.join(file_path, fl)
        with open(f, 'rb') as F:
            n = F.read()

        part = MIMEApplication(n)
        part.add_header('Content-Disposition', 'attachment', filename=Header(fl, "utf-8").encode())
        msg.attach(part)

    # 要把图片嵌入到邮件正文中
    pic_path = os.path.join(file_path, '物业3.PNG')

    with open(pic_path, 'rb') as f:
        pic = MIMEImage(f.read())
        pic.add_header('Content-ID', '<zy>')
        msg.attach(pic)

    body = """
    <p>send email with inside picture</p>
    <img src="cid:zy">
    """
    msg.attach(MIMEText(body, 'html', 'utf-8'))

    my_send_email([receiver], cc, msg)


def send_text_html_file():
    receiver = ['[email protected]', '[email protected]']
    cc = '[email protected]'

    now_time = time.strftime('%Y%m%d_%H%M%S')
    random_int = random.randint(10000, 99999)
    print(now_time, random_int)

    subject = ':'.join(['smtplib-混合', '重要邮件通知', '{} '.format(now_time), '随机码:{}'.format(random_int)])

    msg = MIMEMultipart('mixed')
    msg['from'] = sender
    msg['to'] = ','.join(receiver)
    msg['subject'] = subject
    msg['cc'] = cc

    text = '{} well done '.format(faker.Faker(locale='zh_CN').name())
    text_plain = MIMEText(_text=text, _subtype='plain', _charset='utf-8')
    msg.attach(text_plain)
    

    html = '<p style="font-size:30px;color:orange">{}完成测试</p>'.format(faker.Faker(locale='zh_CN').name())
    text_html = MIMEText(_text=html, _subtype='html', _charset='utf-8')
    msg.attach(text_html)
    
    file_path = r'D:\zy0'
    with open(os.path.join(file_path, 'report_20201221_140614.html'), 'rb') as f:
        html = f.read()
    text_html = MIMEText(_text=html, _subtype='html', _charset='utf-8')
    msg.attach(text_html)


    file_list = [i for i in os.listdir(file_path)]
    file_list.extend([r'D:\0128postman.csv', r'D:\物业2.PNG'])

    for fl in file_list:
        f = os.path.join(file_path, fl)
        # print(f)
        with open(f, 'rb') as file:
            n = file.read()

        # fl = os.path.basename(fl)
        # # print(fl)
        # # file_name最好不要相同,收件邮箱可能会对其重命名
        part = MIMEApplication(n)
        part.add_header('Content-Disposition', 'attachment', filename=Header(fl, "utf-8").encode())
        msg.attach(part)

    my_send_email(receiver, [cc], msg)
    

zmail

# 使用zmail的好处就是不需要输入服务商地址、端口号等


def send_text():
    receiver = '[email protected]'
    cc = '[email protected]'

    now_time = time.strftime('%Y%m%d_%H%M%S')
    random_int = random.randint(10000, 99999)
    print(now_time, random_int)

    subject = ':'.join(['zmail-text', '重要邮件通知', '{} '.format(now_time), '随机码:{}'.format(random_int)])

    text = '1.邮件是由zyooooxie推送;\n2.{}完成测试'.format(faker.Faker(locale='zh_CN').name())

    mail_content = {
    
    
        'subject': subject,
        'content_text': text
    }
    server = zmail.server(username=sender, password=pwd)
    server.send_mail(recipients=receiver, mail=mail_content, cc=cc)


def send_html():
    receiver = ['[email protected]', '[email protected]']
    cc = '[email protected]'

    now_time = time.strftime('%Y%m%d_%H%M%S')
    random_int = random.randint(10000, 99999)
    print(now_time, random_int)

    subject = ':'.join(['zmail-html', '重要邮件通知', '{} '.format(now_time), '随机码:{}'.format(random_int)])

    body = """
    <p style="font-size:10px;color:red;line-height:90px">这由zyooooxie推送</p>
    <p style="font-size:30px;color:orange">{}完成测试</p>
    """.format(faker.Faker(locale='zh_CN').name())

    mail_content = {
    
    
        'subject': subject,
        'content_html': body
    }
    server = zmail.server(username=sender, password=pwd)
    server.send_mail(recipients=receiver, mail=mail_content, cc=cc)


def send_file():
    receiver = '[email protected]'
    cc = ['[email protected]', '[email protected]']

    now_time = time.strftime('%Y%m%d_%H%M%S')
    random_int = random.randint(10000, 99999)
    print(now_time, random_int)

    subject = ':'.join(['zmail-file', '重要邮件通知', '{} '.format(now_time), '随机码:{}'.format(random_int)])

    file_path = r'D:\zy0'

    file_list = [os.path.join(file_path, i) for i in os.listdir(file_path)]

    mail_content = {
    
    
        'subject': subject,
        'attachments': file_list
    }
    server = zmail.server(username=sender, password=pwd)
    server.send_mail(recipients=receiver, mail=mail_content, cc=cc)


def send_text_html_file():
    receiver = ['[email protected]', '[email protected]']
    cc = ['[email protected]', '[email protected]', '[email protected]']

    now_time = time.strftime('%Y%m%d_%H%M%S')
    random_int = random.randint(10000, 99999)
    print(now_time, random_int)

    subject = ':'.join(['zmail-混合', '重要邮件通知', '{} '.format(now_time), '随机码:{}'.format(random_int)])

    file_path = r'D:\zy0'
    file_list = [os.path.join(file_path, i) for i in os.listdir(file_path)]
    file_list.extend([r'D:\0128postman.csv', r'D:\物业2.PNG'])
    text = '1.邮件是由zyooooxie推送;\n2.{}完成测试'.format(faker.Faker(locale='zh_CN').name())

    with open(os.path.join(file_path, 'report_20201221_140614.html'), 'rb') as f:
        html = f.read()

    body = """
    <p style="font-size:10px;color:red;line-height:90px">这由zyooooxie推送</p>
    <p style="font-size:30px;color:orange">{}完成测试</p>
    """.format(faker.Faker(locale='zh_CN').name())

    # 图片添加到正文
    pic = os.path.join(file_path, 'Pycharm_wallpaper——壁纸.jpg')
    with open(pic, 'rb') as f:
        base64_data = base64.b64encode(f.read())

    new_html = """
    <img src="data:image/jpeg;base64,{}">
    """.format(base64_data.decode())

    mail_content = {
    
    
        'subject': subject,
        'attachments': file_list,
        'content_text': text,
        # Gmail始终不显示html的图片【下方2行都可用】
        'content_html': html.decode() + body + new_html
        # 'content_html': [html, body, new_html]

    }

    server = zmail.server(username=sender, password=pwd)
    server.send_mail(recipients=receiver, mail=mail_content, cc=cc)
    # 实际send_mail()代码中 with 已经关闭连接



yagmail


def send_text():
    receiver = '[email protected]'
    cc = '[email protected]'

    # qq邮箱、163邮箱 下面2行 通用;encoding='gbk'是PC的编码,读取file;
    email = yagmail.SMTP(user=gl_acc, password=gl_pwd, host=gl_server, encoding='gbk')
    # email = yagmail.SMTP(user=gl_acc, password=gl_pwd, host=gl_server, encoding='gbk', smtp_ssl=True)

    n = random.randint(10000, 99999)
    subject = '重要通知 yagmail-text:测试完成,随机码:{}'.format(n)
    contents = ['Tester:{} 已经完成测试'.format(f.name()), '第一段text', '第二段text']

    email.send(to=receiver, subject=subject, contents=contents, cc=cc)
    print('邮件发送成功 {}'.format(n))
    email.close()


def send_html():
    receiver = ['[email protected]', '[email protected]']
    cc = '[email protected]'

    email = yagmail.SMTP(user=gl_acc, password=gl_pwd, host=gl_server, encoding='gbk')
    n = random.randint(10000, 99999)
    subject = '重要通知 yagmail-html:测试完成,随机码:{}'.format(n)

    # # 读取html 加载失败
    # with open(r'D:\zy0\百度一下,你就知道.html', 'r', encoding='utf-8') as ff:
    #     n = ff.read()

    html = r'D:\zy0\Pycharm_wallpaper——壁纸.jpg'

    contents = ['html第一段', 'html第二段',
                yagmail.inline(html),
                '<a href="https://www.baidu.com">某度</a>', 
                '<p style="font-size:30px;color:orange">{}完成测试</p>'.format(f.name())]

    email.send(to=receiver, subject=subject, contents=contents, cc=cc)
    print('邮件发送成功 {}'.format(n))
    email.close()


def send_file():
    receiver = '[email protected]'
    cc = ['[email protected]', '[email protected]']

    email = yagmail.SMTP(user=gl_acc, password=gl_pwd, host=gl_server, encoding='gbk')
    n = random.randint(10000, 99999)
    subject = '重要通知 yagmail-file:测试完成,随机码:{}'.format(n)
    # contents列表中本地路径作为附件
    # 但Gmail 会将html作为 正文
    contents = ['Tester:{} 已经完成测试'.format(f.name()), '第一段file', '第二段file',
                r'D:\zy0\report_20201221_140614.html', r'D:\work\企业微信截图_16043843834371.png']

    # 最好不要使用相对路径的.
    file = [r'D:\0128postman.csv', r'D:\物业2.PNG']

    file_path = r'D:\zy0'
    file_list = [os.path.join(file_path, i) for i in os.listdir(file_path)]
    file.extend(file_list)

    email.send(to=receiver, subject=subject, contents=contents, attachments=file, cc=cc)
    print('邮件发送成功 {}'.format(n))
    email.close()



def send_text_html_file():
    receiver = ['[email protected]', '[email protected]']
    cc = ['[email protected]', '[email protected]']

   email = yagmail.SMTP(user=gl_acc, password=gl_pwd, host=gl_server, encoding='gbk')
    n = random.randint(10000, 99999)
    subject = '重要通知 yagmail-混合:测试完成,随机码:{}'.format(n)

    file_path = r'D:\zy0'
    # 给邮件正文嵌入图片
    html = os.path.join(file_path, 'Pycharm_wallpaper——壁纸.jpg')

    file_list = [os.path.join(file_path, i) for i in os.listdir(file_path)]

    contents = ['Tester:{} 已经完成测试'.format(f.name()), '第一段-混合',
                '<p style="font-size:30px;color:orange">{}完成测试</p>'.format(f.name()), '第二段--混合',
                '<p>send email with inside picture</p>',

                # Only needed when wanting to inline an image rather than attach it
                yagmail.inline(html)]

    # Gmail 会将附件的HTML 作为 正文
    # 是因为yagmail库message.py prepare_message()中的代码:
    # # merge contents and attachments for now.
    # if attachments is not None:
    #     for a in attachments:
    #         if not os.path.isfile(a):
    #             raise TypeError("'{0}' is not a valid filepath".format(a))
    #     contents = attachments if contents is None else contents + attachments
    
    email.send(to=receiver, subject=subject, contents=contents, attachments=file_list, cc=cc)
    print('邮件发送成功 {}'.format(n))
    email.close()

实际结果

实际不同邮箱 收到相同邮件时 正文内容、附件内容【文件名、文件是否存在】、邮件数量 有不同;

这一部分 不打算分享;我现在无法确定 相同邮件不同结果 到底是什么原因。

关于发邮件的分享到此为止;

交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie

猜你喜欢

转载自blog.csdn.net/zyooooxie/article/details/113102263
今日推荐