我希望我的 python 脚本从电子邮件列表中逐一发送电子邮件(比如第一个完成然后重复任务并转到第二个直到完成)

I want my python script to send emails 1 by 1 from email list (like 1st done then repeat task and go to second until finish)

我希望我的任务是 1 对 1 而不是批量发送,所以我从电子邮件列表中发送。我希望它发送到第一个然后重复任务并发送到第二个。该代码已经可以正常工作,但它会将所有电子邮件一起批量发送,因此当收件人收到电子邮件时,它就像 header 中包含的所有电子邮件列表一样。这就是为什么我希望它从我的列表中一个接一个地发送它。

import smtplib, ssl
from time import strftime
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from colorama import *
from datetime import datetime


context = ssl.create_default_context()

def get_contacts(filename):
    
    emails = []
    with open(filename, mode='r', encoding='utf-8') as contacts_file:
        for a_contact in contacts_file:
            emails.append(a_contact.split()[0])
    return emails

mails = get_contacts('smtp/contacts.txt')


smtp_user = 'mYsmtp@smtp.com'

def smtp(smtp_server, port, user, password):
    
    
        context = ssl.create_default_context()
        with smtplib.SMTP_SSL(smtp_server, port) as server:
            try:
                 message = MIMEMultipart('alternative')
                 
                 
                 message['Subject'] = 'TESTING'
                 message['From'] = str(Header(f'INFO <{smtp_user}>'))
                 message['To'] = ', '.join(mails)
                
                
                 myfile = open('smtp/letter.txt', 'r')      
                 data = myfile.read()
                 part = MIMEText(data, 'html')
                 message.attach(part)
                
                 now = datetime.now()
                 current_time = now.strftime("%H:%M:%S")
   
                 server.login(user, password)
                 server.sendmail(user, mails, message.as_string())
                 for email in mails:
                    print('\n',email + ''' SENT! ''')
            except smtplib.SMTPAuthenticationError or smtplib.SMTPConnectError :
                 print('Dead SMTP')    
回复:

你只需要移动 put inside 你的 for email in mails:

for email in mails:
    print('\n',email + ''' SENT! ''')
    message['To'] = email
    server.sendmail(user, mails, message.as_string())

从您的原始脚本中删除:

message['To'] = ', '.join(mails)

server.sendmail(user, mails, message.as_string())
备注:
  • 下次考虑在 post 提出您的问题之前先理解您的脚本,因为这是一件非常简单的事情,而且答案已经遍布整个互联网。
  • 您的 try 指令太多,您应该只包含可能因处理错误而失败的指令,因为您正在处理的错误是 smtplib.SMTPAuthenticationErrorsmtplib.SMTPConnectError: server.loginserver.sendmail
  • 不要 post 你的整个脚本或大代码块,这是粗鲁的,你不会以这种方式得到适当的答案。

您的代码非常明确地将所有收件人添加到 To: header,然后发送一条消息。

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

from email.message import EmailMessage
from email.headerregistry import Address

... 

mails = get_contacts('smtp/contacts.txt')


smtp_user = 'mYsmtp@smtp.com'

def generate_messages(recipients):
    with open('smtp/letter.txt', 'r') as myfile:
        data = myfile.read()

    for recipient in recipients:
        message = EmailMessage()
        message['Subject'] = 'TESTING'
        message['From'] = Address("INFO", *smtp_user.split("@"))
        message['To'] = recipient
        message.set_content(data, 'html')                
        yield message

def smtp(smtp_server, port, user, password, messages):
    with smtplib.SMTP_SSL(smtp_server, port) as server:
        server.login(user, password)
        for message in messages:
             now = datetime.now()
             current_time = now.strftime("%H:%M:%S")
             server.send_message(message)

smtp("smtp.example.com", 25, "me@example.com", "xyzzy", generate_messages(mails))

未经测试,我删除了异常处理,因为我可能无法猜出哪种异常处理对这种不同的流程有意义。

如果您是 Python 的新手,使用生成器生成消息可能有点令人困惑。我想你想尽量减少到 SMTP 服务器的单独登录事件的数量,所以代码基本上有一个回调来从 smtp 函数中生成下一条消息。