【发布时间】:2020-02-22 17:35:25
【问题描述】:
我正在 Python 中构建一个自定义电子邮件发件人,使用示例 csv 数据作为输入。我已经完成了大部分脚本,但是我遇到的唯一问题是最后几行代码。如果您运行代码(确保包含您的电子邮件/密码),您会注意到自定义电子邮件会发送给正确的收件人,但是由于循环,他们会收到多个副本。
我在最后尝试了一个简单的中断语句,它只是发送第一封电子邮件然后停止。也无法在 google/youtube 上找到解决方案。
import datetime
import smtplib
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import pandas as pd
host = "smtp.gmail.com"
port = 587
usr = os.environ.get("EMAIL_USER")
pwd = os.environ.get("EMAIL_PASS")
from_email = usr
class MessageUser():
user_details = []
messages = []
email_messages = []
base_message = "Hi {name}!\n\nThank you for the purchase on {date}. We hope you are exited about using it. Just as a reminder the purchase total was ${total}. Have a great day!"
def add_user(self, name, amount, email=None):
name = name[0].upper() + name[1:].lower()
amount = f"{amount}"
detail = {
"name": name,
"amount": amount,
}
today = datetime.date.today()
date_text = '{today.month}/{today.day}/{today.year}'.format(today=today)
detail['date'] = date_text
if email is not None: # if email != None
detail["email"] = email
self.user_details.append(detail)
def get_details(self):
return self.user_details
def make_messages(self):
if len(self.user_details) > 0:
for detail in self.get_details():
name = detail["name"]
amount = detail["amount"]
date = detail["date"]
message = self.base_message
new_msg = message.format(
name=name,
date=date,
total=amount
)
user_email = detail.get("email")
if user_email:
user_data = {
"email": user_email,
"message": new_msg
}
self.email_messages.append(user_data)
else:
self.messages.append(new_msg)
return self.messages
return []
def send_email(self):
self.make_messages()
if len(self.email_messages) > 0:
for detail in self.email_messages:
user_email = detail['email']
user_message = detail['message']
try:
email_conn = smtplib.SMTP(host, port)
email_conn.ehlo()
email_conn.starttls()
email_conn.login(usr, pwd)
the_msg = MIMEMultipart("alternative")
the_msg["Subject"] = "Billing Update"
the_msg["From"] = from_email
the_msg["To"] = user_email
part_1 = MIMEText(user_message, "plain")
the_msg.attach(part_1)
email_conn.sendmail(from_email, [user_email], the_msg.as_string())
except smtplib.SMTPException:
print("Error sending message.")
return True
return False
df = pd.read_csv('test_data.csv')
Name = df.Name
Amount = df.Price
Email = df.Email
for name, amount, email in zip(Name, Amount, Email):
obj = MessageUser()
obj.add_user(f'{name}', f'{amount}', email=f'{email}')
obj.get_details()
obj.send_email()
# Works but need loop break suggestion.
# Previous attempt with error. email.errors.HeaderParseError: header value appears to contain an embedded header.
name = df.Name[1:]
amount = df.Price[1:]
email = df.Email[1:]
obj = MessageUser()
obj.add_user(f'{name}', f'{amount}', email=f'{email}')
obj.get_details()
obj.send_email()
预期:向所有收件人发送一次自定义电子邮件。 实际:由于结束循环,多次收到自定义电子邮件。
【问题讨论】:
-
我不认为这是循环中的问题。您确定
.csv文件中的所有电子邮件都是唯一的吗?你最好重新组织你的班级并检查对偶性。 -
另外,仅供参考,因为我假设您是初学者。您可以将参数直接传递到函数中,而无需
f-strings(obj.add_user(name=name, amount=amount, email=email))。另外,请注意obj.get_details()在您的循环中实际上没有做任何事情。
标签: python string pandas loops smtp