smtplib与gmail - python脚本问题
这是我的脚本:
#!/usr/bin/python
import smtplib
msg = 'Hello world.'
server = smtplib.SMTP('smtp.gmail.com',587) #port 465 or 587
server.ehlo()
server.starttls()
server.ehlo()
server.login('myname@gmail.com','mypass')
server.sendmail('myname@gmail.com','somename@somewhere.com',msg)
server.close()
我只是想从我的 Gmail 账户发送一封邮件。这个脚本使用了 starttls,因为 Gmail 有这个要求。我在两个网络主机上尝试过,分别是 1and1 和 webfaction。1and1 给我一个“连接被拒绝”的错误,而 webfaction 没有报错,但就是不发送邮件。我看不出脚本有什么问题,所以我在想可能和网络主机有关。任何想法和评论都非常感谢。
补充:我开启了调试模式。从输出结果来看,似乎邮件成功发送了……但我就是没有收到。
send: 'ehlo web65.webfaction.com\r\n'
reply: '250-mx.google.com at your service, [174.133.21.84]\r\n'
reply: '250-SIZE 35651584\r\n'
reply: '250-8BITMIME\r\n'
reply: '250-STARTTLS\r\n'
reply: '250-ENHANCEDSTATUSCODES\r\n'
reply: '250 PIPELINING\r\n'
reply: retcode (250); Msg: mx.google.com at your service, [174.133.21.84]
SIZE 35651584
8BITMIME
STARTTLS
ENHANCEDSTATUSCODES
PIPELINING
send: 'STARTTLS\r\n'
reply: '220 2.0.0 Ready to start TLS\r\n'
reply: retcode (220); Msg: 2.0.0 Ready to start TLS
send: 'ehlo web65.webfaction.com\r\n'
reply: '250-mx.google.com at your service, [174.133.21.84]\r\n'
reply: '250-SIZE 35651584\r\n'
reply: '250-8BITMIME\r\n'
reply: '250-AUTH LOGIN PLAIN\r\n'
reply: '250-ENHANCEDSTATUSCODES\r\n'
reply: '250 PIPELINING\r\n'
reply: retcode (250); Msg: mx.google.com at your service, [174.133.21.84]
SIZE 35651584
8BITMIME
AUTH LOGIN PLAIN
ENHANCEDSTATUSCODES
PIPELINING
send: 'AUTH PLAIN *****\r\n'
reply: '235 2.7.0 Accepted\r\n'
reply: retcode (235); Msg: 2.7.0 Accepted
send: 'mail FROM:<myname@gmail.com> size=12\r\n'
reply: '250 2.1.0 OK 4sm652580yxq.48\r\n'
reply: retcode (250); Msg: 2.1.0 OK 4sm652580yxq.48
send: 'rcpt TO:<myname@gmail.com>\r\n'
reply: '250 2.1.5 OK 4sm652580yxq.48\r\n'
reply: retcode (250); Msg: 2.1.5 OK 4sm652580yxq.48
send: 'data\r\n'
reply: '354 Go ahead 4sm652580yxq.48\r\n'
reply: retcode (354); Msg: Go ahead 4sm652580yxq.48
data: (354, 'Go ahead 4sm652580yxq.48')
send: 'Hello world.\r\n.\r\n'
reply: '250 2.0.0 OK 1240421143 4sm652580yxq.48\r\n'
reply: retcode (250); Msg: 2.0.0 OK 1240421143 4sm652580yxq.48
data: (250, '2.0.0 OK 1240421143 4sm652580yxq.48')
9 个回答
你有没有试过构建一个有效的消息呢?
from email.MIMEText import MIMEText
msg = MIMEText('body')
msg['Subject'] = 'subject'
msg['From'] = "..."
msg['Reply-to'] = "..."
msg['To'] = "..."
这里有点自我宣传,但我觉得这是合理的。
你实际上只需要这段代码,就能做到你想要的事情:
import yagmail
yag = yagmail.SMTP('myname@gmail.com')
yag.send('somename@somewhere.com', subject = None, contents = 'Hello')
或者你可以用一行代码来实现:
yagmail.SMTP('myname@gmail.com').send('somename@somewhere.com', None, 'Hello world.')
我建议使用keyring来存储你的密码,这样就不用担心别人看到你脚本里的密码了。
你只需在你的解释器中运行一次以下代码来设置:
import yagmail
yagmail.register("my@gmail.com", "mypassword")
然后退出。接下来你只需使用:
import yagmail
yagmail.SMTP("my@gmail.com") # without password
如果你在主目录下添加一个名为.yagmail的文件,并把"my@gmail.com"放进去,那么你可以直接使用:yagmail.SMTP()
,不过现在这样做其实没什么意义。
提醒一下:如果你打算发送很多信息,最好设置OAuth2,yagmail可以帮你完成这一步。
yagmail.SMTP("my@gmail.com", oauth2_file="/path/to/save/creds.json")
第一次运行时,它会引导你获取OAuth2凭证,并将其存储在文件中,这样下次你就不需要再做任何操作了。 如果你怀疑有人找到了你的凭证,他们的权限会有限,但最好还是通过gmail来撤销他们的凭证。
关于这个包的安装,请查看git或readthedocs,它支持Python 2和3。
我觉得GMail的SMTP服务器会对你连接时使用的IP地址进行反向DNS查找,也就是说,它会检查这个IP地址对应的域名。如果找不到域名,它就会拒绝连接。这样做是为了防止垃圾邮件发送者把他们的SMTP服务器当成一个开放的中转站。