从Python通过sendmail发送邮件
如果我想通过 sendmail 而不是 SMTP 来发送邮件,Python 有没有什么库可以帮我简化这个过程呢?
更好的是,有没有一个好的库可以让我不用考虑 'sendmail 和 smtp 的选择',直接使用就行?
我会在一些 Unix 主机上运行这个脚本,其中只有部分主机在 localhost:25 上监听;而且其中有一些是嵌入式系统,无法设置为接受 SMTP。
作为一种良好的实践,我希望这个库能够自动处理邮件头注入的安全问题——所以直接用 popen('/usr/bin/sendmail', 'w')
这种方式对我来说有点太底层了。
如果答案是 '去写一个库吧,' 那也没关系 ;-)
8 个回答
12
吉姆的回答在我使用Python 3.4时没有效果。我需要在subprocess.Popen()
中添加一个额外的参数universal_newlines=True
。
from email.mime.text import MIMEText
from subprocess import Popen, PIPE
msg = MIMEText("Here is the body of my message")
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True)
p.communicate(msg.as_string())
如果没有universal_newlines=True
,我会得到
TypeError: 'str' does not support the buffer interface
38
这是一个简单的Python函数,它使用Unix系统中的sendmail命令来发送邮件。
def sendMail():
sendmail_location = "/usr/sbin/sendmail" # sendmail location
p = os.popen("%s -t" % sendmail_location, "w")
p.write("From: %s\n" % "from@somewhere.com")
p.write("To: %s\n" % "to@somewhereelse.com")
p.write("Subject: thesubject\n")
p.write("\n") # blank line separating headers from body
p.write("body of the mail")
status = p.close()
if status != 0:
print "Sendmail exit status", status
133
头部注入问题跟你发送邮件的方式无关,而是跟你构建邮件的方式有关。你可以查看一下email这个包,用它来构建邮件,然后把邮件序列化(也就是转换成可以发送的格式),最后通过subprocess模块发送到/usr/sbin/sendmail
。
import sys
from email.mime.text import MIMEText
from subprocess import Popen, PIPE
msg = MIMEText("Here is the body of my message")
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
# Both Python 2.X and 3.X
p.communicate(msg.as_bytes() if sys.version_info >= (3,0) else msg.as_string())
# Python 2.X
p.communicate(msg.as_string())
# Python 3.X
p.communicate(msg.as_bytes())