【问题标题】:send HTMLbody from file using python使用python从文件发送HTMLbody
【发布时间】:2022-01-18 08:19:23
【问题描述】:

我可以发送纯文本但无法发送html格式的html文本。

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

body = """
this is first mail by using python
"""
port_email = 587
smtp_server = "smtp.gmail.com"
password = "your password"


subject = "An email with attachment from Python"
sender_email = "sender@gmail.example.com"
receiver_email = "receiver@example.net"

# Create a multipart message and set headers
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject
message["Bcc"] = receiver_email  # Recommended for mass emails

# Add body to email
message.attach(MIMEText(body, "plain"))
filename = "file name"  # In same directory as script

with open(filename.html, 'r', encoding="utf-8") as attachment:
    part1 = attachment.read()

part2 = MIMEText(part1, "html")
message.attach(part2)
text = message.as_string()

context = ssl.create_default_context()
with smtplib.SMTP_SSL(smtp_server, 465 , context=context) as server:
    server.login(sender_email, password)
    server.sendmail(sender_email, receiver_email, text)

这将发送附件,但我想在电子邮件正文中查看 html 文本。 文件名是内容 html 表格,因此代码应该发送 html 文本,该文本将自动在带有 html 表格的 html 正文中可用。

【问题讨论】:

    标签: python email html-email mime-mail


    【解决方案1】:

    Mime 有多种格式。默认情况下,MIMEMultipart 构建一个 multipart/mixed 消息,表示一个简单的文本正文和一堆附件。

    当你想要一个 HTML 表示的 body 时,你想要一个 multipart/alternative 消息:

    ...
    message = MIMEMultipart('alternative')
    ...
    

    但是您使用的是旧的 compat32 API。从 Python 3.6 开始你最好使用email.message.EmailMessage...

    【讨论】:

    • 我的阅读是他们想要纯 HTML 消息,而不是多部分。如果他们确实发送了multpart/alternativetext/plain 部分应该包含一些有用的信息(即相同的消息,只是不是在 HTML 中),而不是一些随机的垃圾。
    • 感谢@sergeBallesta,我使用了 MIMEMultipart('alternative') 并且它有效我能够在电子邮件正文中发送 HTML 内容,但纯文本会丢失并消失。当我从接收方下载时,附件也会被加密并丢失。
    【解决方案2】:

    如果这不是你想要的,你为什么要传递一个假尸体?

    您的代码似乎是为 Python 3.5 或更早版本编写的。 email 库在 3.6 中进行了大修,现在更加通用和合乎逻辑。可能扔掉你所有的东西,然后重新开始examples from the email documentation.

    这是一个简短的尝试。

    from email.message import EmailMessage
    
    ... 
    message = EmailMessage()
    message["From"] = sender_email
    message["To"] = receiver_email
    message["Subject"] = subject
    # No point in using Bcc if the recipient is already in To:
    
    with open(filename) as fp:
        message.set_content(fp.read(), 'html')
    
    # no need for a context if you are just using the default SSL
    with smtplib.SMTP_SSL(smtp_server, 465) as server:
        server.login(sender_email, password)
        # Prefer the modern send_message method
        server.send_message(message)
    

    如果您想以纯文本和 HTML 格式发送消息,链接的示例将向您展示如何调整代码以执行此操作,但实际上,text/plain 正文部分实际上应该包含有用的消息,而不仅仅是占位符。

    如代码中所述,如果您已经在To: 标头中指定了收件人,则没有理由使用Bcc:。如果您想使用Bcc:,则必须在To: 标头中添加其他内容,通常是您自己的地址或地址列表,如:undisclosed-recipients;

    在打开文件时,Python(或者实际上是操作系统)会检查用户当前的工作目录,而不是加载 Python 脚本的目录。或许也可以看看What exactly is current working directory?

    【讨论】:

    • 谢谢@tripleee 我完全理解。我正在使用 MIMEMultipart(),我需要纯文本、电子邮件正文中的 HTML 内容和 excel 附件。
    • 那么你的意思是说你真的想要垃圾文本/纯文本部分作为 HTML 部分的替代品吗?这是可以做到的,但对于那些不知道有一个他们看不到的实际内容的替代部分的纯文本接收者来说,显然是非常糟糕的。
    • 此时我的建议是让您接受您收到的答案之一(或者,如果您愿意,发布您自己的答案,并在可能的情况下接受)并提出一个新问题您的实际要求。
    • 正如你所说,我问了另一个问题stackoverflow.com/questions/70765339/…
    • 优秀。仍然请将其中一个答案标记为已接受。接受答案通过将您的问题标记为已解决来帮助未来的访问者。另见help.
    猜你喜欢
    • 2015-09-22
    • 2010-09-14
    • 2016-08-03
    • 1970-01-01
    • 2010-09-09
    • 2010-12-06
    • 2019-06-30
    相关资源
    最近更新 更多