python - 有没有办法防止 SMTP 连接超时? smtplib, python

标签 python email timeout smtplib

我有一个需要无限期运行的脚本。该脚本设置为每天通过电子邮件向我发送某些步骤的确认信息。我正尝试为此使用 smtplib。

初始连接已设置,因此我将在脚本启动时使用 getpass 输入我的登录名(写入脚本)和密码。我不想将我的密码写入脚本,甚至不想在配置文件中引用脚本。因此,我想在启动时输入密码并保留 smtp 连接。

按照脚本中的要求重新连接到 smtp 连接将破坏能够完全脱离脚本并使其无限期运行的意义。

我目前使用的示例代码如下所示:

import smtplib
import getpass

smtpObj = smtplib.SMTP('smtp.gmail.com',587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('myemail@gmail.com',password = getpass.getpass('Enter Password: '))

然后我输入密码,输出是:

(235, b'2.7.0 Accepted')

所以这一切都很好。

问题是脚本需要暂停几分钟到几天,具体取决于时间。这是使用带有时间条件的 while 循环实现的,直到调用发送函数的特定时间:

smtpObj.sendmail('myemail@gmail.com','recipient@gmail.com','This is a test')

但是,似乎在大约 20/30 分钟后(即如果暂停足够)。然后 smptObj.sendmail 调用将由于超时错误而失败。

具体报错如下:

SMTPSenderRefused: (451, b'4.4.2 Timeout - closing connection. l22sm2469172wre.52 - gsmtp', 'myemail@gmail.com')

到目前为止,我已经尝试过以下方法:

使用以下超时参数化实例化连接对象:

smtpObj = smtplib.SMTP('smtp.gmail.com',587,timeout=None)
smtpObj = smtplib.SMTP('smtp.gmail.com',587,timeout=86400)

这些似乎都没有抑制连接的“超时”(即同样的问题仍然存在)。

我也尝试过这篇文章中建议的解决方法:

How can I hold a SMTP connection open with smtplib and Python?

然而,这也没有奏效!

我确实想尝试避免每次发送电子邮件时都必须重新连接的解决方案,因为我只想手动输入一次连接密码,而不是写入直接或间接将其添加到脚本中。

肯定有办法解决超时问题!如果有人可以在这里提供帮助,请告诉我!不过,如果您认为在脚本需要发送电子邮件之前重新连接的更“明显”的解决方案是更好的方法,请告诉我。

谢谢!...

最佳答案

如果您不想在脚本中包含敏感凭证,您应该使用环境变量。

从终端 shell(在 python 之外):

$ EXPORT secretVariable=mySecretValue
$ echo $secretVariable
$ mySecretValue
$

所以要在您的代码中利用它...

>>> import os
>>> myPW = os.getenv('secretVariable')
>>> myPW
'mySecretVal'
>>>

这样,您就不必手动输入密码了。除此之外,尝试让一个空闲的 SMTP 连接一次打开可能几天是不太实际的,只需实现一个 try/except 结构。

import smtplib
import os

def smtp_connect():
    # Instantiate a connection object...
    password = os.getenv('secretVariable')
    smtpObj = smtplib.SMTP('smtp.gmail.com',587)
    smtpObj.ehlo()
    smtpObj.starttls()
    smtpObj.login('myemail@gmail.com',password=password)
    return smtpObj

def smtp_operations():
    try:
        # SMTP lib operations...
        smtpObj.sendmail('myemail@gmail.com','recipient@gmail.com','This is a test')
        # SMTP lib operations...

    except Exception: # replace this with the appropriate SMTPLib exception

        # Overwrite the stale connection object with a new one
        # Then, re-attempt the smtp_operations() method (now that you have a fresh connection object instantiated).
        smtpObj = smtp_connect() 
        smtp_operations()

smtpObj = smtp_connect()
smtp_operations()

通过将 except Exception 替换为当连接失效时引发的实际 SMTP Exception,您将确保不会捕获不存在的异常t 与连接失效有关。

因此,使用 try/except,脚本将尝试 执行 SMTP 操作。如果连接失效,它将实例化一个新的连接对象,然后尝试使用新的连接对象重新执行自身。

关于python - 有没有办法防止 SMTP 连接超时? smtplib, python ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49203706/

相关文章:

python - 如何将多个pickle文件放入一个pickle文件中

python - 获取位大小 N 的所有可能的位组合

c# - 如何在 ASP.Net 中保存和打开 SMTP 邮件

email - 使用 wp_mail,仅在 Gmail 帐户中未收到电子邮件(Yahoo 和 Hotmail 都可以)

java - 无法使用 python requests 模块发送 `multipart/form-data` 请求

python - 如何在 python 中搜索特定的 Outlook 电子邮件

php - Codeigniter 电子邮件始终从 'my@gmail.com' 发送,而不是给定的输入电子邮件

java - Android:AndroidHttpClient - 如何设置超时?

javascript - 使用超时/间隔的 jQuery 图像幻灯片/旋转横幅问题

php - 在 PHP 中使用 cURL 下载大文件 - 页面挂起