python3 新式邮件写法 附件乱码 解决

import sys
import re
import mimetypes
import base64
import traceback
from pathlib import PurePath
from datetime import date
from calendar import monthrange

import smtplib
from email.headerregistry import Address, Group
from email.utils import localtime, make_msgid
from email.message import EmailMessage

邮件服务器 = "smtp.exmail.qq.com"
邮件服务器_端口 = 465
发送者账号 = "public@qq.com"
发送者密码 = "Admin"
发送者昵称 = "公司"



def get_type(path):
    ctype, encoding = mimetypes.guess_type(path)
    if ctype is None or encoding is not None:
        ctype = 'application/octet-stream'
    return ctype.split('/', 1)


def dd_b64(headstr):
    """对邮件header及附件的文件名进行两次base64编码,防止outlook中乱码。email库源码中先对邮件进行一次base64解码然后组装邮件,所以两次编码"""
    headstr = '=?utf-8?b?' + base64.b64encode(headstr.encode('UTF-8')).decode() + '?='
    headstr = '=?utf-8?b?' + base64.b64encode(headstr.encode('UTF-8')).decode() + '?='
    return headstr


def make_msg(to_name, to_addrs, html_table):
    msg = EmailMessage()
    msg['From'] = Address(dd_b64(发送者昵称), addr_spec = 发送者账号)  # 省略addr_spec会出现 由 xxx 代发
    msg['To'] = Address(dd_b64(to_name), addr_spec = to_addrs)
    msg['Subject'] = 邮件主题
    msg['Date'] = localtime()

    msg_cid = make_msgid()
    html_table = html_table.replace('</body>', f'<img src="cid:{msg_cid[1:-1]}" width="300"/></body>')
    msg.add_alternative(html_table, subtype = 'html')
    # msg.set_content(html_table,subtype = 'html')
    path = r"E:\OneDrive\图片\壁纸\forests2.jpg"
    with open(path, 'rb') as img:
        msg.get_payload()[0].add_related(img.read(), *get_type(path), cid = msg_cid)

    path = r"C:\Users\sharp\Desktop\新建 Microsoft Excel 工作表.xlsx"
    with open(path, 'rb') as fi:
        msg.add_attachment(fi.read(), *get_type(path), filename = dd_b64(PurePath(path).name))

    return msg


server = smtplib.SMTP_SSL(邮件服务器, 邮件服务器_端口)
server.login(发送者账号, 发送者密码)
server.send_message(msg)

 

解决乱码的中心就是先两次base64,原因在代码的注释中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值