12

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

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,则电子邮件发送为空白。我相信':'导致这个问题的原因,所以我试图逃避它,但没有。

4

3 回答 3

17

问题是smtplib没有在邮件标题和邮件正文之间放置一个空行,如我的测试的“显示原始”表单所示:

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邮件内容提供的“信封”,但如果您希望您的收件人(及其邮寄者)很好地处理邮件,那么您应该更完整,但您可能应该使用电子邮件模块来生成正文。

添加

根据其中的 doctest,smtplib.py这似乎是一个有意的功能,允许调用者sendmail()附加到标题:

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

From:和线是我上面提到Subject:的“漂亮”标题的一部分。

于 2012-08-03T14:08:53.810 回答
2

正确的解决方案是使用 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')

诚然,它稍微有点冗长,但也无限多才多艺、健壮和可扩展。

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

于 2019-03-09T15:09:34.473 回答
0

我不认为这与冒号有关,而是与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')

顺利通过。

于 2012-08-03T13:53:45.800 回答