首页 > 代码库 > 朋友,我用python给你发了一封邮件
朋友,我用python给你发了一封邮件
— 1. Start —
在某个周末,心血来潮,我想给我远方的朋友发送电子邮件,跟他分享我要在CSDN开设顺哥读源码的专栏。于是我登陆新浪邮箱,写下这样的内容:
鼠标轻击“发送”按钮,我远在千里之外的朋友就可以看到我给他写的邮件了
沿着这个思路YY下去,我要怎么才能让我的朋友知道我完成了新的博客呢?每次写完都像上面这样写邮件告诉他?要是朋友比较多呢?那不是忙死顺哥啊。要是能够在每次更新博客之后自动发送邮件通知朋友是不是很好?
我拿出工作电脑开始翻看以前写过的发送告警邮件的代码,python真是一门简单到爆的编程语言,发送邮件只需要几行关键代码。如果你也想跟我一样通过python给朋友发送邮件,你首先需要一台电脑,电脑上还需要安装了python,然后你需要注册一个邮箱地址,下面是我的开发环境:
主题 | 限制 |
---|---|
python版本 | 2.7.5 |
操作系统 | windows7 |
依赖 | smtplib |
邮件服务器 | smtp.sina.com |
除了上面的开发环境外,我们还需要做一些准备工作,比如申请邮箱地址、想好邮件主题、邮件正文等,就像下面这样
主题 | 描述 | 是否必需 |
---|---|---|
邮箱地址 | 电子邮件网络中的身份标识,本文将使用的邮箱地址:cug_heshun@sina.com | 是 |
邮箱密码 | 邮箱地址访问邮件服务器时的密码,本文使用密码:**********(可以猜猜是什么哦) | 是 |
收件人列表 | 邮件接收人的列表(一个或者多个邮箱地址),本文使用:anys_test@sina.com,60550295@qq.com | 是 |
抄送列表 | 邮件抄送列表(一般抄送给那些需要知道邮件所述内容但不需要做任何事的人) | 否 |
邮件主题 | 邮件所描述内容的概括,本文使用:“顺哥读源码” | 是 |
邮件正文 | 邮件的主题部分内容,本文使用:“我亲爱的朋友:我打算在CSDN开设“顺哥读源码”的专栏,欢迎前来我的地盘留下你宝贵的意见,我们一起成长!” | 是 |
邮件附件 | 以文件的形式(word文档、excel表格、图片、视频等)添加到邮件后面,严格来讲属于邮件正文的一部分 | 否 |
顺哥是个懒惰的人,为了减少输入,我们先把需要的信息保存在变量,就像下面这样:
# encoding: utf-8
import smtplib
smtp_server_addr = ‘smtp.sina.com‘
email_address = ‘cug_heshun@sina.com‘
email_password = ‘**********‘
send_to_list = [‘605502954@qq.com‘, ‘anys_test@sina.com‘]
subject = u"顺哥读源码"
message = u"""
我亲爱的朋友:
我打算在CSDN开设“顺哥读源码”的专栏,欢迎前来我的地盘留下你宝贵的意见,我们一起成长!
"""
— 2. Send Mail —
准备工作到这里就算完成了,让我们来编写发送邮件的代码,编写完成之后可能是这样的:
# encoding: utf-8
import smtplib
smtp_server_addr = ‘smtp.sina.com‘
email_address = ‘cug_heshun@sina.com‘
email_password = ‘**********‘
send_to_list = [‘605502954@qq.com‘, ‘anys_test@sina.com‘]
subject = u"顺哥读源码"
message = u"""
我亲爱的朋友:
我打算在CSDN开设“顺哥读源码”的专栏,欢迎前来我的地盘留下你宝贵的意见,我们一起成长!
"""
if __name__ == ‘__main__‘:
smtp_server = smtplib.SMTP(smtp_server_addr)
smtp_server.login(email_address, email_password)
smtp_server.sendmail(email_address, send_to_list, message)
与之前相比,添加了三行代码:
- smtp_server = smtplib.SMTP(smtp_server_addr) ,创建连接到smtp_server_addr的连接,有很多个参数,完整的定义如下:
smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])
,如果指定了host则实例化时连接到服务器,此时使用第二个参数指定的port或者默认的端口:25.如果未指定需要在登录服务器前调用SMTP.connect([host[, port]])
来建立连接 - smtp_server.login(email_address, email_password),登录。要通过邮件服务器发送邮件,必须先登录认证通过
- smtp_server.sendmail(email_address, send_to_list, message),发送邮件。完整定义如下:
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
— 3. UnicodeEncodeError —
激动吗?我要成功了,我可以通过python给我的朋友发送邮件了,好,让我们运行一下:
send: u‘\r\n\u6211\u4eb2\u7231\u7684\u670b\u53cb\uff1a\r\n \u6211\u6253\u7b97\u5728CSDN\u5f00\u8bbe\u201c\u987a\u54e5\u8bfb\u6e90\u7801\u201d\u7684\u4e13\u680f\uff0c\u6b22\u8fce\u524d\u6765\u6211\u7684\u5730\u76d8\u7559\u4e0b\u4f60\u5b9d\u8d35\u7684\u610f\u89c1\uff0c\u6211\u4eec\u4e00\u8d77\u6210\u957f\uff01\r\n.\r\n‘
Traceback (most recent call last):
File "E:/workspace/Demo/smtp_send_mail/send_mail.py", line 20, in <module>
smtp_server.sendmail(email_address, send_to_list, message)
File "C:\Python27\lib\smtplib.py", line 736, in sendmail
(code, resp) = self.data(msg)
File "C:\Python27\lib\smtplib.py", line 503, in data
self.send(q)
File "C:\Python27\lib\smtplib.py", line 323, in send
self.sock.sendall(str)
File "C:\Python27\lib\socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 2-8: ordinal not in range(128)
这是什么鬼?为什么他不能正常工作?看错误信息应该是编码问题,查阅相关资料之后发现,我们需要使用email这个python内置的模块来完成邮件信息的组织,下面是改善后的版本:
# encoding: utf-8
from email.mime import text
import smtplib
smtp_server_addr = ‘smtp.sina.com‘
email_address = ‘cug_heshun@sina.com‘
email_password = ‘**********‘
send_to_list = [‘605502954@qq.com‘, ‘anys_test@sina.com‘]
subject = u"顺哥读源码"
message = u"""
我亲爱的朋友:
我打算在CSDN开设“顺哥读源码”的专栏,欢迎前来我的地盘留下你宝贵的意见,我们一起成长!
"""
if __name__ == ‘__main__‘:
msg = text.MIMEText(message, ‘plain‘, ‘utf-8‘)
smtp_server = smtplib.SMTP(smtp_server_addr)
smtp_server.login(email_address, email_password)
smtp_server.sendmail(email_address, send_to_list, msg.as_string())
我们from email.mime import text
,使用msg = text.MIMEText(message, ‘plain‘, ‘utf-8‘)
来构造邮件正文,在发送时先通过msg.as_string()
将其转换为字符串。好,这样应该可以了吧,我们再试一下:
C:\Python27\python.exe E:/workspace/Demo/smtp_send_mail/send_mail.py
Process finished with exit code 0
哇,没报错,这是成功了吗?我好激动,让我们看看‘605502954@qq.com‘, ‘anys_test@sina.com‘
有没有收到邮件
— 4. Humanize —
邮件是收到了,但似乎有一些不好的地方:
- 邮件没有主题
- 没有发件人
我们对代码做进一步的修改,为邮件添加主题和发件人
# encoding: utf-8
from email.header import Header
from email.mime import text
from email.utils import parseaddr, formataddr
import smtplib
smtp_server_addr = ‘smtp.sina.com‘
email_address = ‘cug_heshun@sina.com‘
email_password = ‘**********‘
send_to_list = [‘605502954@qq.com‘, ‘anys_test@sina.com‘]
subject = u"顺哥读源码"
message = u"""
我亲爱的朋友:
我打算在CSDN开设“顺哥读源码”的专栏,欢迎前来我的地盘留下你宝贵的意见,我们一起成长!
"""
if __name__ == ‘__main__‘:
msg = text.MIMEText(message, ‘plain‘, ‘utf-8‘)
msg[‘From‘] = formataddr((Header(u‘顺哥‘, ‘utf-8‘).encode(), email_address))
msg[‘Subject‘] = Header(subject, ‘utf-8‘).encode()
smtp_server = smtplib.SMTP(smtp_server_addr)
smtp_server.login(email_address, email_password)
smtp_server.sendmail(email_address, send_to_list, msg.as_string())
新添加了下面的两行:
msg[‘From‘] = formataddr((Header(u‘顺哥‘, ‘utf-8‘).encode(), email_address))
msg[‘Subject‘] = Header(subject, ‘utf-8‘).encode()
去吧,孩子,看看你的成果:
朋友,我用python给你发了一封邮件