我当前的脚本允许我很好地发送电子邮件,但它只是不喜欢一些字符,特别是本示例中的':'
。
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 theren how are you?"
,它运行良好,但假设我尝试发送一个url http://www.neopets.com
,则电子邮件发送为空白。我相信':'
导致了这个问题,所以我试图逃避它,但什么都没有。
问题是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
提供的"信封",但如果你希望收件人(及其邮件发件人)能很好地处理邮件,邮件的内容应该更完整,你可能应该使用电子邮件模块来生成正文。
添加
根据smtplib.py
中的doctest,这似乎是一个有意的功能,允许sendmail()
的调用方附加到标头:
>>> msg = '''\
... From: Me@my.org
... Subject: testin'...
...
... This is a test '''
>>> s.sendmail("me@my.org", tolist, msg)
其中From:
和Subject:
行是我上面提到的"漂亮"标题的一部分。
正确的解决方案是使用Python email
库来创建有效的消息,而不是费力地学习(或随机猜测)如何通过将文本片段连接在一起来构建有效的MIME消息结构。
使用可以很容易地创建只包含ASCII的琐碎RFC822消息
"From: {0}nTo: {1}nSubject: {2}nn{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")
诚然,它稍微更详细,但也更加通用、健壮和可扩展。
这使用了EmailMessage
API,它是在Python 3.6中正式引入的。新代码可能应该针对这个平台,而不是早期版本的遗留email.Message
模块(或MIMEMultipart
、MIMEText
等组件),尽管您可以找到的大多数在线代码示例都是针对旧的Python库的。有关一些快速示例,请参阅Python email
示例文档。
我不认为这与冒号有关,但它与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')
一切顺利。