smtplib发送空白信息如果消息包含某些字符

2024-06-17 12:03:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我当前的脚本允许我很好地发送电子邮件,但是有些字符它不喜欢,特别是在这个示例中':'

import smtplib, sys

mensaje = sys.argv[1]
def mailto(toaddrs, msg):
    fromaddr = 'myemailblabla'

    username = 'thisismyemail'
    password = '122344'

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(username, password)
    server.sendmail(fromaddr, toaddrs, msg)
    server.quit()

mailto('test@gmail.com', mensaje)

如果我写了一个示例消息,比如说"Hi there\n how are you?",它工作得很好,但是假设我尝试发送一个url http://www.neopets.com,电子邮件将被发送为空白。我相信':'会导致这个问题,所以我试图逃离它,但什么也没有。


Tags: 脚本com示例server电子邮件sysusernamemsg
3条回答

正确的解决方案是使用Pythonemail库创建一个有效的消息,而不是费力地学习(或胡乱猜测)如何通过将文本片段连接在一起来构造一个有效的MIME消息结构。

一个只包含ASCII的普通RFC822消息可以很容易地用

'From: {0}\nTo: {1}\nSubject: {2}\n\n{3}'.format(
    fromaddr, toaddr,
    'Hello, I am the exiled prince of Ubandingba',
    'http://clickme.example.net/scam/')

但是,只要你需要任何其他字符集、超过80个字符的行、纯文本以外的内容类型,或者通常比1990年的电子邮件更高级的内容类型,代码就应该类似于

from email.message import EmailMessage

msg = EmailMessage()
msg['from'] = fromaddr
msg['to'] = toaddr
msg['subject'] = 'You have been nominated for the Nobel prize'
msg.set_content('http://scam.example.org/clickme')

这是公认的稍微冗长,但也无限多的通用性,健壮性和可扩展性。

这使用了Python 3.6中正式引入的EmailMessageAPI。新代码可能应该针对这个平台,而不是早期版本中的遗留email.Message模块,尽管您可以找到的大多数在线代码示例都是针对较旧的Python库的。

问题是smtplib没有在消息头和消息体之间放置空行,如我的测试的“Show Original”表单中所示:

Return-Path: <me@gmail.com>
Received: **REDACTED**
        Fri, 03 Aug 2012 06:56:20 -0700 (PDT)
Message-ID: <501bd884.850c320b@mx.google.com>
Date: Fri, 03 Aug 2012 06:56:20 -0700 (PDT)
From: me@gmail.com
http: //www.example.com

虽然这是合法的邮件头,但是邮件传输代理和邮件用户代理应该忽略他们不理解的明显的头字段。由于RFC822头一直持续到第一个空行,http:看起来像一个头行,所以它被解析为一个头。如果有换行符:

mensaje = '\nhttp://www.example.com'

然后它按预期工作。虽然从技术上讲,电子邮件只需要smtplib提供的“信封”,但如果您希望收件人(及其邮件发件人)能够很好地处理邮件,则邮件内容应该更完整,您可能应该使用email模块来生成正文。

已添加

根据smtplib.py中的doctest,这似乎是一个有意的特性,允许sendmail()的调用方附加到头:

     >>> msg = '''\\
     ... From: Me@my.org
     ... Subject: testin'...
     ...
     ... This is a test '''
     >>> s.sendmail("me@my.org", tolist, msg)

其中From:Subject:行是我上面提到的“nice”头的一部分。

我认为这不是关于冒号,而是关于http://开始消息。

mailto('test@gmail.com', 'http://www.url.com')
mailto('test@gmail.com', 'http://www.url.com that is a url')
mailto('test@gmail.com', ' http://www.url.com')

都失败了,但是:

mailto('test@gmail.com', 'Here is a url http://www.url.com')

过得很好。

相关问题 更多 >