在 python 的 while 循环中更新 "To:" Email-Header

Updating "To:" Email-Header in a while loop in python

下面是向从文本文件加载的联系人发送多封电子邮件的代码。

import time
    from time import sleep

    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    import smtplib

    uname = #testmail@gmail.com
    name = "KTester"
    password = #password1
    server = smtplib.SMTP('smtp.gmail.com: 587')
    server.starttls()
    server.login(uname, password)
    message="Test"

    msg = MIMEMultipart('Alternative')
    f= open("list.txt","r")clear

    if f.mode == "r":
      cont = f.read().splitlines()
      for x in cont:
        print time.ctime()

        msg['Subject'] = "Test Mail - cripted Sample"
        msg['To'] = x
        msg['From'] = name+"\x0A\x0D"+uname
        msg.attach(MIMEText(message, 'html'))

        print "successfully sent email to %s:" % (msg['To'])

    f.close()
    server.quit()

输出:

在这种情况下,第一次编译就是预期的结果,如果我们使用print "successfully sent email to %s:" % (x)

就可以得到

变量 'x' 在每次迭代结束时更改其值。

但是,msg['To'] = x 不接受循环第二次迭代的值(上面的第二个代码 运行)。

赋值操作不适用于消息 object。

请帮助解决问题。谢谢!

(原始答案的编辑,在澄清问题的输出后)

尝试将以下行移动到 for 循环中:

msg = MIMEMultipart('Alternative')

看起来像这样:

for x in cont:
    msg = MIMEMultipart('Alternative')
    print time.ctime()

    msg['Subject'] = "Test Mail - cripted Sample"
    msg['To'] = x
    msg['From'] = name+"\x0A\x0D"+uname
    msg.attach(MIMEText(message, 'html'))

    print "successfully sent email to %s:" % (msg['To'])

我认为 msg 需要在每次迭代中都是新的。

我的测试产生了完全相同的结果 - 似乎一遍又一遍地发送到同一个电子邮件地址。因为 msg headers 只是附加到。 for 循环正在创建多个到:headers,但打印只显示第一个。请参阅下面的调试内容:

Header of To: line in original for loop

Output of original for loop

在 for 循环中添加 msg 实例化后,每次迭代的输出都如预期的那样具有不同的名称。

我认为 msg 结构的根源可能是电子邮件在收件人:行上可以有多个人。上面的解决方案假定您只希望每个人在 to: 行上有一个人。

脚本中的主要问题是您在 for 循环之外定义了 msg = MIMEMultipart('Alternative')。尝试在 for loop.[=12= 中定义 msg = MIMEMultipart('Alternative') ]

The solution is same as given by @Daniel Sims but I have turned your script more readable so that everyone can understand

我用我自己的方式编辑了你的代码,这对我来说很有魅力。试试看:

[代码]

import time
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# credentials    
uname = 'your email address'
name = "KTester"
password = 'password'

# Connecting to gmail server and logging to your gmail account
server = smtplib.SMTP('smtp.gmail.com: 587')
server.starttls()
server.login(uname, password)

message = "Test"  # Your message

with open('list.txt', 'r') as lst:
    lines = lst.readlines()  # Reading files to get emails

    for line in lines:  # Getting each email from list of emails
        msg = MIMEMultipart('Alternative')   # This line is added here(which if you have did outside of the for loop)
        msg['Subject'] = "Test Mail - cripted Sample"
        msg['To'] = line
        msg['From'] = '{}{}{}'.format(name, "\x0A\x0D", uname)
        msg.attach(MIMEText(message, 'html'))

        print(time.ctime())
        print("successfully sent email to {}".format(msg['To']))

 server.quit()

此行为是设计使然。

重新分配给 msg['to'] 不会覆盖现有邮件 header,它会添加另一个。要将现有消息发送到新地址,您需要在设置之前删除 'to' header。

del msg['to']
msg['to'] = 'spam@example.com'

这也适用于其他 header。来自 Message.__setitem__ 的文档:

Note that this does not overwrite or delete any existing header with the same name. If you want to ensure that the new header is the only one present in the message with field name name, delete the field first, e.g.:

del msg['subject']

msg['subject'] = 'Python roolz!'