8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png
Python发送smtp邮件带附件 Python
admin 9月前

Python发送smtp邮件带附件

import smtplib
from email.message import EmailMessage
from email.headerregistry import Address, Group
import email.policy
import mimetypes
import base64


class SendEmail(object):
    """
    python3 发送邮件类
    格式: html
    可发送多个附件
    """
    def __init__(self, smtp_server, smtp_user, smtp_passwd, sender, recipient):
        # 发送邮件服务器,常用smtp.163.com
        self.smtp_server = smtp_server
        # 发送邮件的账号
        self.smtp_user = smtp_user
        # 发送账号的客户端授权码
        self.smtp_passwd = smtp_passwd
        # 发件人
        self.sender = sender
        # 收件人
        self.recipient = recipient

        # Use utf-8 encoding for headers. SMTP servers must support the SMTPUTF8 extension
        # https://docs.python.org/3.6/library/email.policy.html
        self.msg = EmailMessage(email.policy.SMTPUTF8)

    def set_header_content(self, subject, content):
        """
        设置邮件头和内容
        :param subject: 邮件题头
        :param content: 邮件内容
        :return:
        """
        self.msg['From'] = self.sender
        self.msg['To'] = self.recipient
        self.msg['Subject'] = subject
        self.msg.set_content(content, subtype="html")

    def set_accessories(self, path_list: list):
        """
        添加附件
        :param path_list: [{"path": ""}, {"name": ""}]
        :return:
        """
        for path_dict in path_list:
            filename = path_dict['path']
            name = path_dict['name']
            ctype, encoding = mimetypes.guess_type(filename)
            if ctype is None or encoding is not None:
                # No guess could be made, or the file is encoded (compressed), so
                # use a generic bag-of-bits type.
                ctype = 'application/octet-stream'
            maintype, subtype = ctype.split('/', 1)
            with open(filename, 'rb') as fp:
                self.msg.add_attachment(fp.read(), maintype, subtype, filename=self.dd_b64(name))

    def send_email(self):
        """
        发送邮件
        :return:
        """
        with smtplib.SMTP_SSL(self.smtp_server) as smtp:
            # HELO向服务器标志用户身份
            smtp.ehlo_or_helo_if_needed()
            # 登录邮箱服务器
            smtp.login(self.smtp_user, self.smtp_passwd)
            print("Email:{}==>{}".format(self.sender, self.recipient))
            smtp.send_message(self.msg)
            print("Sent succeed!")

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


if __name__ == '__main__':
    smtp_server = "smtp.xxxx.cn"
    smtp_user = "xxx@xxxx.cn"  # 发送邮件的账号
    smtp_passwd = "xxxxxx@"  # 发送账号的客户端授权码
    # 直接用字符串也行,这里为了方便使用 display name, 相当于 "测试-发送者 <a@163.com>"
    # 发送号码要与登录号码一致
    sender = Address("测试-发送者", "mail", "iccat.cn")
    # 发送多个人
    recipient = Group(addresses=(Address("测试-接受者", "xxxxx", "qq.com"), Address("测试-接受者", "xxxx", "xxxxxx.top")))
    subject = "测试专用测试附件"
    content = """
        <!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body {
      font-family: Arial, sans-serif;
    }
    .table-container {
      max-width:500px;
    }
    .table-container td {
      padding: 8px;
      text-align: center;
      border-bottom: 1px solid #ddd;
    }
    .table-container th {
      background-color: #f2f2f2;
      text-align: center;
	  width: 5em;
    }
	table {
      width: 100%;
	  margin-right: 20px;
      border-collapse: collapse;
	  text-align: center;
    }
  </style>
</head>
<body>
  <h2>两率指标计算结果如下:</h2>
  <div class="table-container">
    <table>
      <tr>
        <th>日期</th>
        <td>20231206</td>
      </tr>
    </table>
    <table>
      <tr>
        <th>指标</th>
        <td>流动性覆盖率(LCR)%</td>
		<td>净稳定资金率(NSFR)%</td>
      </tr>
    </table>
	<table>
      <tr>
        <th>指标限额</th>
        <td style="text-align:center;">200%</td>
      </tr>
    </table>
	<table>
      <tr>
        <th>指标值</th>
        <td>80</td>
		<td>899</td>
      </tr>
    </table>
  </div>
  <P>请及时处理。</p>
</body>
</html>
        """
    path_list = [{"path": r"./测试文件123abc.txt",
                  "name":  "测试文件123abc.txt"},{"path": r"./生成汇款单测试.mp4",
                  "name":  "生成汇款单测试.mp4"}]
    sd = SendEmail(smtp_server, smtp_user, smtp_passwd, sender, recipient)  # 创建对象
    sd.set_header_content(subject, content)  # 设置题头和内容
    sd.set_accessories(path_list)  # 添加附件
    sd.send_email()  # 发送邮件
上传的附件:
  • smtp带附件.py (大小:5.38K,下载次数:0)5.38K | 更新于: 2023-12-07 11:33:51
最新回复 (0)
    • 朕弟分享 | 专注小众,乐于分享!
      2
          
返回
发新帖 搜索 反馈 回顶部