Python发送邮件太慢

2 投票
4 回答
10339 浏览
提问于 2025-04-17 05:53

我有下面这个脚本,用来发送大约10条消息给自己。不过,我发现用Python发送消息的速度真的很慢。去年我需要一个系统来发送大约200封带附件和文字的邮件,我用msmtp和bash实现的。记得那时候速度快多了。

把while循环放到smtp_serv.sendmail(sender, recepient, msg)这个函数里面,结果也差不多。

我是不是做错了什么?肯定不能比bash加msmtp慢吧(而且我只是在发送“嗨”这条消息,没有附件)。

#! /usr/bin/python3.1

def sendmail(recepient,  msg):

    import smtplib

    # Parameters
    sender = 'login@gmail.com'
    password = 'password'
    smtpStr = 'smtp.gmail.com'
    smtpPort = 587
    # /Parameters

    smtp_serv = smtplib.SMTP(smtpStr, smtpPort)
    smtp_serv.ehlo_or_helo_if_needed()
    smtp_serv.starttls()
    smtp_serv.ehlo()

    recepientExists = smtp_serv.verify(recepient)
    if recepientExists[0] == 250:
        smtp_serv.login(sender, password)
        try:
            smtp_serv.sendmail(sender, recepient, msg)
        except smtplib.SMTPException:
            print(recepientExists[1])
    else:
        print('Error',   recepientExists[0], ':',  recepientExists[1])

    smtp_serv.quit()

for in in range(10):
    sendmail('receiver@gmail.com',  'hi')

4 个回答

2

也许我说的有点晚,但我觉得这跟这个问题很相关。最近我也遇到了同样的问题,经过搜索我发现,连接SMTP服务器的过程可能会很耗时,这主要是因为域名解析的问题,因为SMTP服务器需要进行反向查找来验证连接的客户端。

在我的情况下,这个过程大约花了1分钟!:

s = smtplib.SMTP(smtp_server)

解决办法是修复Linux系统上的域名解析问题。之后,连接速度就变得很快了。

希望这对你有帮助。

3

你每次发送邮件时,都是先打开SMTP服务器的连接,然后再关闭。这种做法其实不太高效。更好的方法是,在发送所有邮件的时候保持连接一直打开。

6

在这个脚本中,建立SMTP连接的时间是发送一封邮件的五倍(需要5秒),而发送邮件只需要1秒。所以,建立一个连接后发送多封邮件会更合理,而不是每次都重新建立连接:

#!/usr/bin/env python3
import smtplib    
from contextlib import contextmanager
from datetime   import datetime
from email.mime.text import MIMEText
from netrc      import netrc
from timeit     import default_timer as timer

@contextmanager
def logined(sender, password, smtp_host='smtp.gmail.com', smtp_port=587):
    start = timer(); smtp_serv = smtplib.SMTP(smtp_host, smtp_port, timeout=10)
    try: # make smtp server and login
        smtp_serv.ehlo_or_helo_if_needed()
        smtp_serv.starttls()
        smtp_serv.ehlo()
        print('smtp setup took (%.2f seconds passed)' % (timer()-start,))
        start = timer(); smtp_serv.login(sender, password)
        print('login took %.2f seconds' % (timer()-start,))
        start = timer(); yield smtp_serv
    finally:
        print('Operations with smtp_serv took %.2f seconds' % (timer()-start,))
        start = timer(); smtp_serv.quit()
        print('Quiting took %.2f seconds' % (timer()-start,))

smtp_host = 'smtp.gmail.com'
login, _, password = netrc().authenticators(smtp_host)
with logined(login, password, smtp_host) as smtp_serv:
    for i in range(10):
        msg = MIMEText('#%d timestamp %s' % (i, datetime.utcnow()))
        msg['Subject'] = 'test #%d' % i
        msg['From'] = login
        msg['To'] = login
        smtp_serv.send_message(msg) 

输出

smtp setup took (5.43 seconds passed)
login took 0.40 seconds
Operations with smtp_serv took 9.84 seconds
Quiting took 0.05 seconds

如果你的Python版本没有.send_message()这个功能,你可以使用:

smtp_serv.sendmail(from, to, msg.as_string())

撰写回答