如何使用Python发送电子邮件?

8

我正在编写一个使用Python发送电子邮件的程序。从各种论坛中我学到以下代码:

#!/usr/bin/env python
import smtplib
sender = "sachinites@gmail.com"
receivers = ["abhisheks@cse.iitb.ac.in"]
yourname = "Abhishek Sagar"
recvname = "receptionist"
sub = "Testing email"
body = "who cares"
message = "From: " + yourname + "\n" 
message = message + "To: " + recvname + "\n"
message = message + "Subject: " + sub + "\n" 
message = message + body
try:
    print "Sending email to " + recvname + "...",
    server = smtplib.SMTP('smtp.gmail.com:587')
    username = 'XYZ@gmail.com'  
    password = '*****'  
    server.ehlo()
    server.starttls()  
    server.login(username,password)  
    server.sendmail(sender, receivers, message)         
    server.quit()
    print "successfully sent!"
except  Exception:
    print "Error: unable to send email"

但是它只是在终端上打印“错误:无法发送电子邮件”,然后退出。我该如何解决这个问题?
我修改了最后两行:
except Exception, error:
    print "Unable to send e-mail: '%s'." % str(error)

我收到了以下错误信息:
Traceback (most recent call last):
  File "./2.py", line 45, in <module>
    smtpObj = smtplib.SMTP('localhost')
  File "/usr/lib/python2.6/smtplib.py", line 239, in __init__
    (code, msg) = self.connect(host, port)
  File "/usr/lib/python2.6/smtplib.py", line 295, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/usr/lib/python2.6/smtplib.py", line 273, in _get_socket
    return socket.create_connection((port, host), timeout)
  File "/usr/lib/python2.6/socket.py", line 514, in create_connection
    raise error, msg
socket.error: [Errno 111] Connection refused

我看到你是新来的stackoverflow用户,欢迎!请确保使用编辑帮助来正确格式化你的帖子。这有助于我们更轻松地阅读你的问题,并增加你获得答案的机会。 - André Caron
3个回答

16

如果消息头和负载中包含非ASCII字符,则它们应该被编码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from email.header    import Header
from email.mime.text import MIMEText
from getpass         import getpass
from smtplib         import SMTP_SSL


login, password = 'user@gmail.com', getpass('Gmail password:')
recipients = [login]

# create message
msg = MIMEText('message body…', 'plain', 'utf-8')
msg['Subject'] = Header('subject…', 'utf-8')
msg['From'] = login
msg['To'] = ", ".join(recipients)

# send it via gmail
s = SMTP_SSL('smtp.gmail.com', 465, timeout=10)
s.set_debuglevel(1)
try:
    s.login(login, password)
    s.sendmail(msg['From'], recipients, msg.as_string())
finally:
    s.quit()

Gmail现在对可以登录帐户的设备进行了严格限制。如果像我一样,在远程机器上使用此类代码时遇到问题,您可以尝试登录Gmail帐户并检查“允许不安全的应用程序”选项。还有授权特定应用程序的工具可供使用。 - jprockbelly
1
@jprockbelly:不要妥协安全。即使帐户启用了两步验证,也可以使用它。只需为您的脚本生成一个应用程序密码即可。 - jfs

6
如果你打印错误信息,你很可能会得到一个详细的描述发生了什么错误。试一下这个(没有任何幽默意味):
try:
    # ...
except Exception, error:
    print "Unable to send e-mail: '%s'." % str(error)

如果在阅读错误信息后你仍然不能理解你的错误,请更新你的问题并附上错误信息,我们可以为你提供更多帮助。
另外提供信息后更新: 错误信息:

socket.error: [Errno 111] Connection refused

这意味着远程端点(例如GMail SMTP服务器)拒绝网络连接。如果你查看smtplib.SMTP构造函数,似乎你应该更改:
server = smtplib.SMTP('smtp.gmail.com:587')

以下是需要翻译的内容。

server = smtplib.SMTP(host='smtp.gmail.com', port=587)

按照您所说的做了之后,我遇到了以下错误:正在发送邮件给接待员... 无法发送电子邮件:'[Errno 110] Connection timed out'。由于我在代理后面,所以我需要在代码中添加额外的内容吗? - Abhishek Sagar
@AbhishekSagar:SMTP配置是一个复杂的话题。也许你可以尝试使用其他端口?请参阅Gmail常见问题中的配置其他电子邮件客户端 - André Caron
是的,我安装了Postfix,但当我搜索配置SMTP时放弃了这个想法!它真的很复杂。 - Abhishek Sagar

0
根据错误信息,您使用本地主机作为SMTP服务器,然后连接被拒绝了。我猜您的本地主机没有运行SMTP服务器,您需要确保您连接的SMTP服务器是有效的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接