如何使用Python 2.7发送带附件的邮件

2 投票
1 回答
2506 浏览
提问于 2025-04-18 02:36

我在用这个代码通过本地IP发送邮件时遇到了错误,有什么建议可以解决这个套接字错误吗?

def SendTMail(self):
# Import the email modules we'll need

# Open a plain text file for reading.  For this example, assume that
# the text file contains only ASCII characters.
#try:
    fp = open('testint.txt', 'rb')
    # Create a text/plain message
    msg = MIMEText(fp.read())
    testfile = 'TESTING REPORT'
    fp.close()

    me = '124@hotmail.co.uk'
    you = '123@live.com'
    msg['Subject'] = 'The contents of %s' % testfile
    msg['From'] = me
    msg['To'] = you

    # Send the message via our own SMTP server, but don't include the
    # envelope header.
    s = smtplib.SMTP('192.168.1.3')
    s.sendmail(me, [you], msg.as_string())
    s.quit()     

错误信息如下:

File "x:\example.py", line 6, in SendTMail s = smtplib.SMTP('192.168.1.3') 
File "x:\Python27\lib\smtplib.py", line 251, in init (code, msg) = self.connect(host, port)
File "x:\Python27\lib\smtplib.py", line 311, in connect self.sock = self._get_socket(host, port, self.timeout)
File "x:\Python27\lib\smtplib.py", line 286, in _get_socket return socket.create_connection((host, port), timeout)
File "x:\Python27\lib\socket.py", line 571, in create_connection raise err – 
error: [Errno 10051] A socket operation was attempted to an unreachable network

1 个回答

2

在发布代码之前,我想先简单解释一下,关于你在问题评论中提到的内容。

smtplib是用来连接现有的SMTP服务器的。你可以把它想象成Outlook Express。Outlook是一个客户端(或者说是一个邮件用户代理,如果你想用更专业的说法)。它本身并不发送邮件,而是连接到它配置好的SMTP服务器,告诉那个服务器:"嘿,我是用户xxx@hotmail.com(这是我的密码来证明我身份)。你能帮我发送这封邮件吗?"

如果你想的话,自己搭建一个SMTP服务器也是可以的(比如在Linux上,Postfix是一个容易配置的SMTP服务器,Windows上也有很多类似的选择)。一旦你搭建好,它就会开始在通常是25号端口监听连接,如果通过这个端口传来的数据符合SMTP协议,它就会把邮件发送到目的地。在我看来,这个主意现在并不是很好。原因是现在每个(靠谱的)邮件提供商都会把来自未验证SMTP服务器的邮件视为垃圾邮件。如果你想发送邮件,依赖一个知名的SMTP服务器(比如smtp.live.com,也就是hotmail使用的那个)会更好,使用你的用户名和密码进行身份验证,然后通过它发送邮件(就像SMTP中继那样)。

说到这里,这里有一些代码可以通过smtp.live.com发送一封带有附件borrajax.jpeg的HTML邮件。

你需要编辑下面的代码,设置你的hotmail密码(如果你的hotmail用户名不是124@hotmail.co.uk,也要修改用户名),以及邮件的接收者。我出于安全原因在测试后把我的信息从代码中删除了...对我来说:-D,然后把我在你问题中看到的内容放回去了。此外,这段脚本假设在运行Python脚本的同一目录下找到了一个名为borrajax.jpeg的图片:

import smtplib
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def send_mail():
    test_str="This is a test"
    me="124@hotmail.co.uk"
    me_password="XXX"   # Put YOUR hotmail password here
    you="123@live.com"
    msg = MIMEMultipart()
    msg['Subject'] = test_str
    msg['From'] = me
    msg['To'] = you
    msg.preamble = test_str
    msg_txt = ("<html>"
                "<head></head>"
                "<body>"
                    "<h1>Yey!!</h1>"
                    "<p>%s</p>"
                "</body>"
            "</html>" % test_str)
    msg.attach(MIMEText(msg_txt, 'html'))
    with open("borrajax.jpeg") as f:
        msg.attach(MIMEImage(f.read()))
    smtp_conn = smtplib.SMTP("smtp.live.com", timeout=10)
    print "connection stablished"
    smtp_conn.starttls()
    smtp_conn.ehlo_or_helo_if_needed()
    smtp_conn.login(me, me_password)
    smtp_conn.sendmail(me, you, msg.as_string())
    smtp_conn.quit()

if __name__ == "__main__":
    send_mail()

当我运行这个例子时(如我所说,我编辑了发件人和收件人),它通过我的(旧)hotmail账户成功发送了一封邮件到一个Gmail账户。这是我在Gmail中收到的内容:

Gmail截图

你可以用email这个Python模块做很多事情。玩得开心!!

编辑:

真是的!!你关于附加文本文件的评论让我一直放不下!!:-D 我必须亲自试试。根据这个问题的详细说明,我添加了一些代码来附加一个文本文件。

msg_txt = ("<html>"
            "<head></head>"
            "<body>"
                "<h1>Yey!!</h1>"
                "<p>%s</p>"
            "</body>"
        "</html>" % test_str)
msg.attach(MIMEText(msg_txt, 'html'))
with open("borrajax.jpeg", "r") as f:
    msg.attach(MIMEImage(f.read()))
#
# Start new stuff
#
with open("foo.txt", "r") as f:
    txt_attachment = MIMEText(f.read())
    txt_attachment.add_header('Content-Disposition',
                              'attachment',
                               filename=f.name)
    msg.attach(txt_attachment)
#
# End new stuff
#
smtp_conn = smtplib.SMTP("smtp.live.com", timeout=10)
print "connection stablished"

没错,它可以工作... 我在运行脚本的同一目录下有一个foo.txt文件,它可以正确地作为附件发送。

撰写回答