我刚刚被分配了创建代码以通过电子邮件自动发送图表报告的任务。图像应嵌入到 HTML 中以便更好地阅读,并且每个报告我只应发送 1 封电子邮件。我以前从未接触过 HTML,但是我设法想出了下面的代码:
def enviar_email():
body = """
<html>
<body>
<p>Prezados,</p>
<p>Expectativas IPCA Anual</p>
<p>
<img src="cid:image0" alt="Error" width="600" height="300">
</p>
<p>Expectativas IPCA Média vs. Meniada</p>
<p>
<img src="cid:image1" alt="Error" width="600" height="300">
<img src="cid:image2" alt="Error" width="600" height="300">
</p>
<p>
<img src="cid:image3" alt="Error" width="600" height="300">
<img src="cid:image4" alt="Error" width="600" height="300">
</p>
<p>
<img src="cid:image5" alt="Error" width="600" height="300">
</p>
<p>Expectativas IPCA Ponderado vs. Ult 5 dias</p>
<p>
<img src="cid:image6" alt="Error" width="600" height="300">
<img src="cid:image7" alt="Error" width="600" height="300">
</p>
<p>
<img src="cid:image8" alt="Error" width="600" height="300">
<img src="cid:image9" alt="Error" width="600" height="300">
</p>
<p>
<img src="cid:image10" alt="Error" width="600" height="300">
</p>
<p>Expectativas IPCA Anual</p>
<p>
<img src="cid:image11" alt="Error" width="600" height="300">
<img src="cid:image12" alt="Error" width="600" height="300">
</p>
<p>
<img src="cid:image13" alt="Error" width="600" height="300">
</p>
<p>Expectativas IPCA Mensal</p>
<p>
<img src="cid:image14" alt="Error" width="600" height="320">
<img src="cid:image15" alt="Error" width="600" height="320">
</p>
<p>
<img src="cid:image16" alt="Error" width="600" height="320">
</p>
<p>Expectativas PIB</p>
<p>
<img src="cid:image17" alt="Error" width="600" height="300">
<img src="cid:image18" alt="Error" width="600" height="300">
</p>
<p>
<img src="cid:image19" alt="Error" width="600" height="300">
<img src="cid:image20" alt="Error" width="600" height="300">
</p>
<p>Expectativas Taxa Selic</p>
<p>
<img src="cid:image21" alt="Error" width="600" height="300">
<img src="cid:image22" alt="Error" width="600" height="300">
</p>
<p>
<img src="cid:image23" alt="Error" width="600" height="300">
<img src="cid:image24" alt="Error" width="600" height="300">
</p>
<p>Expectativas Câmbio</p>
<p>
<img src="cid:image25" alt="Error" width="600" height="300">
</p>
<body>
<html>
"""
msg = MIMEMultipart()
msg['Subject'] = 'SUBJECT'
msg['From'] = 'EMAIL'
msg['To'] = 'EMAIL'
password = 'dcau ogjy pdct rqhl'
msg.attach(MIMEText(body, 'html'))
*#iterating through diretories to get the images and assigning them a index value*
index = 0
main_dir_path = 'K:\Temp\Ramiro\Relatório Focus out'
sub_dir_path = glob.glob(main_dir_path + '/*')
for graf_dir_path in sub_dir_path:
graf_path = glob.glob(graf_dir_path + '/*.png')
for graf in graf_path:
with open(graf, 'rb') as fp:
img = MIMEImage(fp.read(), _subtype='png')
img.add_header('Content-ID', f'<image{index}>')
msg.attach(img)
index += 1
*# Login Credentials for sending the mail
smtp = smtplib.SMTP('smtp.gmail.com: 587')
smtp.starttls()
smtp.login(msg['From'], password)
smtp.sendmail(msg['From'], [msg['To']], msg.as_string().encode('utf-8'))
print('Email enviado')
enviar_email()
代码并不漂亮,但完成了它应该做的事情。很伤心,我试图找出改进的方法。我想减少 html 部分中硬编码行的数量,但我做不到。任何建议都非常受欢迎,并对我的英语不好感到抱歉:)。
您可以动态创建 HTML,而不是对所有
<img>
标签进行硬编码,特别是因为您已经在循环访问目录和附加到图像的文件。
我将首先定义一个基本的 HTML 结构,并向其中插入动态内容,这将使您的代码更加灵活,并且可以为未来的更改提供开放性。我将使模板代码具有该部分的名称,然后是每个部分的占位符。 (例如。
{image_section_1}
)。
然后我将创建一个字典(
image_sections
),其中每个键都是一个 image_section (或任何您决定命名的占位符),并且值设置为空字符串。
在 for 循环中,在继续下一个项目之前,我将在此处添加动态代码。我设置了一个
section_key
变量并将其设置为 f 字符串 f'image_section{index // 2 + 1}
(因为每个部分有 2 个图像,并且使编号基于 1 而不是基于 0,因为我们的字典是基于 1 的)
然后我会创建一个
img_tag
变量,其中包含所有图像规格,但 src 为 cid:image{index}
(我会保持 alt、宽度、高度规格相同)
然后我会告诉我的循环在部分键访问我的字典并添加 img_tag (
image_sections[section_key] += f'<p>{img_tag}</p>
)
现在我将使用之前的模板(可能称为
body_template
或其他)和 python 的 .format() 方法解压字典并将其键和值作为参数传递。它会说:
body = body_template.format(**image_sections)
但实际上,如果您没有实施上述任何一项,请安全地处理密码。建议使用环境变量以避免对敏感数据进行硬编码。设置环境变量非常容易,我知道在我的 mac 上我在终端中运行的命令是:
export EMAIL_PASSWORD="your-email-password"
然后在我的代码中我将设置一个指向我的环境变量的变量:
password = os.getenv('EMAIL_PASSWORD')
我希望这是一个足够清楚的解释。如果我可以进一步澄清自己,请告诉我。