python-3.x ValueError:邮件中最多只能有1个To标头

41ik7eoe  于 2023-03-20  发布在  Python
关注(0)|答案(5)|浏览(92)

我试图写一个非常基本的电子邮件发送脚本。这是我的代码..

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg.set_content("Test message.")
msg['Subject'] = "Test Subject!!!"
msg['From'] = "myemail@gmail.com"

email_list = ["xyz@gmail.com", "abc@gmail.com"]

for email in email_list:
    msg['To'] = email
    server = smtplib.SMTP(host='smtp.gmail.com', port=587)
    server.starttls()
    server.login("myemail@gmail.com", "mypassword")
    server.send_message(msg)
    server.quit()

脚本应该发送邮件给多个收件人,所以,我需要改变msg['To']字段时,通过循环迭代,但我得到了以下错误的追溯波纹管。

Traceback (most recent call last):
  File "exp.py", line 66, in <module>
    msg['To'] = email
  File "/usr/lib/python3.8/email/message.py", line 407, in __setitem__
    raise ValueError("There may be at most {} {} headers "
ValueError: There may be at most 1 To headers in a message

我该怎么解决?请帮帮忙。谢谢。

g2ieeal7

g2ieeal71#

清除消息的“收件人”属性。

for email in email_list:
    msg['To'] = email
    server = smtplib.SMTP(host='smtp.gmail.com', port=587)
    server.starttls()
    server.login("myemail@gmail.com", "mypassword")
    server.send_message(msg)
    server.quit()
    del msg['To]

下面是抛出异常的代码:(\Python 385\资料库\电子邮件\消息. py)

def __setitem__(self, name, val):
    """Set the value of a header.

    Note: this does not overwrite an existing header with the same field
    name.  Use __delitem__() first to delete any existing headers.
    """
    max_count = self.policy.header_max_count(name)
    if max_count:
        lname = name.lower()
        found = 0
        for k, v in self._headers:
            if k.lower() == lname:
                found += 1
                if found >= max_count:
                    raise ValueError("There may be at most {} {} headers "
                                     "in a message".format(max_count, name))
    self._headers.append(self.policy.header_store_parse(name, val))
o2rvlv0m

o2rvlv0m2#

由于不知道EmailMessage类的内部工作原理,我可以假设每次调用__setitem__都会写入电子邮件消息的头部,因此通过在循环中调用它,头部会被写入多次。我的建议是为要发送的每封电子邮件创建一个电子邮件消息,但只创建一个服务器:

server = smtplib.SMTP(host='smtp.gmail.com', port=587)
server.starttls()
server.login("myemail@gmail.com", "mypassword")
email_list = ["xyz@gmail.com", "abc@gmail.com"]
for email in email_list:
    msg = EmailMessage()
    msg.set_content("Test message.")
    msg['Subject'] = "Test Subject!!!"
    msg['From'] = "myemail@gmail.com"
    msg['To'] = email
    server.send_message(msg)
server.quit()

仅当您需要单独发送邮件时。如果您想同时向每个人发送相同的邮件,您可以执行以下操作

msg['To'] = ', '.join(email_list)
nvbavucw

nvbavucw3#

如果你有一个地址列表,其中一些包含名字/头衔,那么我认为这是正确的方法。请注意,parseaddr + formataddr对可能不需要,但parseaddr可以纠正一些格式错误的收件人。

from email.header import Charset
from email.message import EmailMessage, MIMEPart
from email.utils import formataddr, parseaddr

test_recipients = [
        "Mr. John Doe <johndoe@example.com>",
        "Mr. Jane Doe <janedoe@example.com>",
        "somebody@example.com"
]
to_header= []
for raw_address in (test_recipients):
    # Parse and recreate
    title, email = parseaddr(raw_address)
    if title and email:
        to_header.append(f"{title} <{email}>")
    elif email:
        to_header.append(email)
# Encode after join
message.add_header("To", Charset("utf-8").header_encode(", ".join(to_header)))
kr98yfug

kr98yfug4#

如果您只是从循环中删除server.quit()并添加del msg [′ to ′],则不会出现错误

atmip9wb

atmip9wb5#

# original code
for email in email_list:
    msg['To'] = email
    server = smtplib.SMTP(host='smtp.gmail.com', port=587)
    server.starttls()
    server.login("myemail@gmail.com", "mypassword")
    server.send_message(msg)
    server.quit()

把“server.quit“换成“def msg['to']”就是我让它工作的方法!

# new code
for email in email_list:
    msg['To'] = email
    server = smtplib.SMTP(host='smtp.gmail.com', port=587)
    server.starttls()
    server.login("myemail@gmail.com", "mypassword")
    server.send_message(msg)
    del msg['To']

相关问题