1

smtplib我正在尝试使用 Gmail 和Python 中的模块发送短信。

基本功能已实现,使用以下代码,我完全可以在手机上接收这些短信:

server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login('email', 'password')
server.sendmail('email', 'recipient', '\nhttp://apple.com') 

现在,提及我正在发送一个链接可能会有所帮助。有人可能想知道为什么我\n在示例链接前面插入了 ;显然,没有它,smtplib会将链接作为标头处理,因此会发送一条空消息。

但是,我的消息中添加了一个换行符,如下所示:

http://apple.com
newline here

我无法理解为什么会这样:

  • smtplib 添加换行符是因为消息是链接吗?
  • 是因为我以 SMS 形式接收消息吗?
  • Gmail 是否添加了换行符?
4

1 回答 1

2

to的msg参数sendmail不是消息体,而是整个消息。因此,它必须是有效的 RFC(2)822 消息。

正如文档末尾的注释所说:

通常,您会希望使用电子邮件包的功能来构造电子邮件,然后您可以将其转换为字符串并通过 sendmail() 发送;请参阅电子邮件:示例。

但是,上面的示例显示了如何自己生成简单的消息:

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
       % (fromaddr, ", ".join(toaddrs)))

如果您想知道什么构成有效的电子邮件,请参阅RFC 2822(可能还有RFC 822,它被 2822 取代,但有一些有用的不同解释和示例)。但简短的版本是这样的:它是一系列标题行,每行都以 结尾\r\n,然后是一个空行(意思是\r\n\r\n),然后是消息正文。

所以,从技术上讲,你的代码甚至不应该工作,因为它只是有一个\n而不是\r\n前缀。

更重要的是,您发送的消息根本没有标题。甚至你可能认为你包括的From:and也不包括在内。To:正如文档sendmail所说:

from_addr 和 to_addrs 参数用于构造传输代理使用的消息信封。SMTP 不会以任何方式修改邮件标头。

这可能会或可能不会被各种服务器视为无效(或垃圾邮件)。

同时,末尾额外的换行符是因为所有行都必须以a结尾\r\n,而SMTP是面向行的协议。如果消息不以换行符结尾,则根本没有办法表明消息已完成。

如果您想了解详细信息,请参阅RFC2821,其中解释了 SMTP 协议。具体来说,请看 2.3.1 邮件对象、2.3.7 行和 4.1.1.4 数据(DATA)。但简短的版本是发送消息需要一个 DATA 命令,该命令必须以 结尾\r\n.\r\n,并且“这个终止序列的第一个也是结束数据(消息文本)最后一行的那个”。这意味着无法发送不以换行符结尾的消息。

如果你真的想要,可以通过将你的正文封装在 MIME 消息中来解决这个问题;MIME 消息本身当然会以换行符结尾,但这不会影响您封装的正文。有几种方法可以做到这一点 - 但您需要收件人能够处理您发送的任何内容,我猜这些方法都不适用于电子邮件-SMS 网关(更不用说 SMS 接收端点了) )。

于 2012-11-09T00:07:32.237 回答