python smtplib快速发送邮件/更高效

时间:2013-11-19 11:14:17

标签: python smtplib

我创建了一个小的python脚本,将大约11000封邮件(* .eml)转发到我的邮件服务器。这些邮件附有CSV文件,其中包含每日能量测量数据。

所以,我的方法工作正常,但发送邮件大约需要20分钟左右!有什么想法加快这个速度吗?

#! /usr/bin/env python
import os, sys
import email, smtplib


storage_folder = "data/export"
storage_header = 0

mail_server = 'server-address'
mail_username = 'mail-user'
mail_password = 'mail-password'

mail_to = 'mail-address-to'
mail_from = 'mail-sender'


def load_local_mails(file_folder):
    #: scan desired folder for *.eml files
    email_body = []

    for dirname, dirnames, filenames in os.walk(file_folder):
        for filename in filenames:
            if filename.endswith('eml'):
                f = open(os.path.join(dirname, filename))
                email_body.append(f.read())
    return email_body


def send_mail(email_body):
    #: send mails
    smtp = smtplib.SMTP(mail_server, 587)
    smtp.starttls()
    smtp.login(mail_username, mail_password)

    for idx, item in enumerate(email_body):
        m = email.message_from_string(item)
        m.replace_header("From", mail_from)
        m.replace_header("To", mail_to)
        m.replace_header("Subject", m['subject'])

        smtp.sendmail(mail_from, mail_to, m.as_string())
        print "Forwarding mail %d/%d: '%s' from '%s' to %s " % (idx+1, len(email_body), m['subject'], m['date'], mail_to)

    smtp.quit()


def main():
    if len(sys.argv) > 1:
        if sys.argv[1] == '--start':
            send_mail(load_local_mails(sys.argv[2]))

    else:
        exit("Don't know what to do? :(. Goodbye")


if __name__ == '__main__':
    main()

更新:我能够管理直接(SCP)上传到qmail环境中的特定文件夹。我认为这是最快的解决方案!无论如何,感谢您的建议。

2 个答案:

答案 0 :(得分:1)

嗯,你没有提供太多数据,但对于smtp协议的大量电子邮件来说,20分钟看起来并不合理。使用smtp,您必须与服务器交换5条消息。

  1. HELO
  2. 来自
  3. 的邮件
  4. 邮寄至
  5. 数据
  6. 退出
  7. 当你假设10ms ping你的目的地时,只给出11k * 50ms = 550s网络延迟开销。大概是10分钟。

    然后你需要实际打开并阅读11k文件它也可能需要一段时间,也许不是那么多。但是您没有指定发送数据的大小。也许它可以解释其余的时间。特别是如果您说发送csv数据文件。

    如果不改变您使用的技术解决方案,将很难加快速度。但我建议最好使用压缩将数据作为二进制文件传输到更大的块中。压缩应该对csv文件有意义。

答案 1 :(得分:1)

由于这是一个网络绑定任务,您可以通过将任务分成较小批量并并行执行来加快速度。

使用这种方法你应该很容易达到几分钟。

周围有很多lib可以做到这一点,我个人会去gevent,但如果你想坚持使用标准库,你可以坚持使用多处理/线程。