尝试改进 - Python 电子邮件代码和 HTML

问题描述 投票:0回答:1

我刚刚被分配了创建代码以通过电子邮件自动发送图表报告的任务。图像应嵌入到 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 部分中硬编码行的数量,但我做不到。任何建议都非常受欢迎,并对我的英语不好感到抱歉:)。

邮件输出示例: The result:

python html-email smtplib
1个回答
0
投票

您可以动态创建 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')

我希望这是一个足够清楚的解释。如果我可以进一步澄清自己,请告诉我。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.