在用 email/smtplib 发送的邮件中结合纯文本和 HTML

Combining plain text and HTML in a mail sent with email/smtplib

使用给定的示例 here, I've written some code 发送一封在页脚中带有超链接的纯文本电子邮件:

def send_mail(subject, removed_ids, added_ids):
    parser = ConfigParser()
    parser.read('config.ini')
    from_address = parser.get('smtp', 'from')
    to_address  = parser.get('smtp', 'to')
    subject = subject
    host = parser.get('smtp', 'host')
    port = parser.get('smtp', 'port')
    password = parser.get('smtp', 'password')

    msg = MIMEMultipart('alternative')
    msg['From'] = from_address
    msg['To'] = to_address
    msg['Subject'] = subject

    body = 'The following Instruction IDs have been removed:\n'
    for id in removed_ids:
        body = body + id + '\n'
    for id in added_ids:
        body = body + id + '\n'
    body = body + '\n'
    body = body + 'The following Instruction IDs have been added:\n'
    msg.attach(MIMEText(body, 'plain'))
    msg.attach(MIMEText(EMAIL_BODY_FOOTER_HYPERLINK_TO, 'html'))

    server = smtplib.SMTP(host, port)
    server.starttls()
    server.login(from_address, password)
    text = msg.as_string()
    server.sendmail(from_address, to_address, text)
    server.quit()

在我添加 HTML 部分之前,纯文本显示正常。现在添加后:

msg = MIMEMultipart('alternative')
msg.attach(MIMEText(body, 'plain'))
msg.attach(MIMEText(EMAIL_BODY_FOOTER_HYPERLINK_TO, 'html'))

现在已收到 HTML 页脚,但电子邮件完全缺少本应位于其前面的纯文本。我哪里做错了?

您误解了多部分消息的工作原理。

纯文本和 HTML 部分不是 "joined" 客户端以任何方式提供的。 两个 部分都应包含整个消息。 HTML-clients 将显示 HTML 部分。无法显示 HTML 的文本客户端将显示文本部分并忽略 HTML 部分。

因此您也需要将您的消息包含到 HTML 部分,可能会转义或以其他方式 HTML 格式化。

当然,将您的 URL 也包含在纯文本部分会很好,只是不要将其包装在 <a> 标记中。大多数客户端都非常擅长检测纯文本电子邮件中的 URL 并突出显示它们,这样您的收件人就不会因为使用纯文本电子邮件客户端而丢失任何内容。