在工作中,每天或者每周结束的时候我们都会发送相应的日报或者周报给上级领导,来汇报你做了那些工作,可是汇报工作内容的时候我们始终都是打开邮箱、写入内容,发送和抄送给固定的人,那么这么繁琐并且重复的一件事,我们能不能使用程序来简化?
答案是可以的,接下来我们就使用Python来操作邮箱,自动的进行邮件的发送操作。
Python中有两个内置的库:smtplib和email, 这两个库结合使用就可以实现,其中smtplib库负责通信(发送邮件),email库负责构造邮件的内容和格式。
那么接下来我们先来看下发送邮件的思路。
一、发送邮件思路
发送一封邮件大概的思路为:登录、写邮件、发送, 但是每一步也包含了很多过程,接下来我们慢慢看。
登录: 我们要用程序通过邮箱服务器地址连通邮箱服务器,然后借用SMTP协议通过用户名和授权码进行登录。
写邮件: 需要构造邮箱的发件人、收件人、邮件主题、邮件内容(文本、附件)等。
发送: 借助连通好的服务器和登录好的账号,在SMTP协议上,通过收件人地址进行邮件发送。
SMTP协议
SMTP 的全称是Simple Mail Transfer Protocol,即简单邮件传输协议。
它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。 SMTP 认证,简单地说就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,这就使得那些垃圾邮件的散播者无可乘之机。 增加 SMTP 认证的目的是为了使用户避免受到垃圾邮件的侵扰。
二、代码编写
(1)先导入smtplib库,进行账号登录(在此以QQ邮箱为例)。
下面会用到一个叫做授权码的东西,相当于你账号的密码,但是此处不能写密码,要去邮箱中获取对应的授权码(下方提供了教程),获取到的授权码保存好,防止泄露,并且请把邮箱服务开启。
import smtplib
# 发件人邮箱地址
sendAddress = ‘xxx@qq.com’
# 发件人授权码
password = ‘xxxxxxxx’
# 连接服务器
server = smtplib.SMTP_SSL(‘smtp.qq.com’, 465)
# 登录邮箱
loginResult = server.login(sendAddress, password)
print(loginResult)
上方代码正确执行结果应该是(235, b’Authentication successful’),状态码235表示认证成功。
注意:
连接服务器表示登录哪家的邮箱账号就连接哪家的服务器进行认证,下面列举部分邮箱服务器地址,发送邮件就写465端口号。
邮箱 |
服务器 |
新浪邮箱 |
smtp.sina.com |
搜狐邮箱 |
smtp.sohu.com |
126邮箱 |
smtp.126.com |
QQ邮箱 |
smtp.qq.com |
163邮箱 |
smtp.163.com |
(2)接下来导入email库,用于构造邮件内容,邮件内容包括发件人、收件人、抄送人、主题、正文、附件等。
先介绍下MIMEMultipart、MIMEText等方法,这是邮件消息构造对象,用来将一封邮件的各个部分组成一条消息,MIMEMultipart和MIMEText**组合可以同时给邮件添加正文和附件,如果不需要添加附件只需要使用MIMEText,简单来说,上述方法用于规范邮件。
注意电子邮件的形式,我们一般会把发件人、收件人、抄送人写成昵称<邮箱地址>的形式,如果有多个发件人、收件人、抄送人,使用分号;隔开,邮件正文要在创建邮件消息对象的时候以子内容的身份添加进去,同时要指定子内容类型和编码类型,子内容类型默认为’plain’,编码类型默认为’us-ascii’,但是我们可以根据发送邮件内容不同将内容类型和编码类型进行修改。
构造一封没有附件的邮件:
from email.mime.text import MIMEText
# 正文
content = “””
尊敬的用户您好:
附件中为您申请的个人乘机凭证,请查收。手机查看可能出现乱码现象,请您在电脑上查看即可。
使用航旅纵横“验真服务-行程单验真”功能可以扫描凭证中的二维码检验信息。如有任何建议与意见,欢迎通过APP中的意见反馈与我们交流,谢谢您的使用。
“””
# 定义一个可以添加正文的邮件消息对象
msg = MIMEText(content, ‘plain’, ‘utf-8’)
# 发件人昵称和地址
msg[‘From’] = ‘xxx<xxx@qq.com>’
# 收件人昵称和地址
msg[‘To’] = ‘xxx<xxx@qq.com>;xxx<xxx@qq.com>’
# 抄送人昵称和地址
msg[‘Cc’] = ‘xxx<xxx@qq.com>;xxx<xxx@qq.com>’
# 邮件主题
msg[‘Subject’] = ‘xxxxxx’
构造一封带有附件的邮件:
在下方代码中,我将添加附件时MIMEText中的’plain’换成了’base64’,这是因为MIMEText规范化的内容类型不同,要使用与之对应的参数。
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 定义一个可以添加正文和附件的邮件消息对象
msg = MIMEMultipart()
# 发件人昵称和地址
msg[‘From’] = ‘xxx<xxx@qq.com>’
# 收件人昵称和地址
msg[‘To’] = ‘xxx<xxx@qq.com>;xxx<xxx@qq.com>’
# 抄送人昵称和地址
msg[‘Cc’] = ‘xxx<xxx@qq.com>;xxx<xxx@qq.com>’
# 邮件主题
msg[‘Subject’] = ‘xxxxxx’
# 正文
content = “””
尊敬的用户您好:
附件中为您申请的个人乘机凭证,请查收。手机查看可能出现乱码现象,请您在电脑上查看即可。
使用航旅纵横“验真服务-行程单验真”功能可以扫描凭证中的二维码检验信息。如有任何建议与意见,欢迎通过APP中的意见反馈与我们交流,谢谢您的使用。
“””
# 先通过MIMEText将正文规范化,构造成邮件的一部分,再添加到邮件消息对象中
msg.attach(MIMEText(content, ‘plain’, ‘utf-8’))
# 附件(添加多个附件同理)
# 以二进制形式将文件的数据读出,再使用MIMEText进行规范化
attachment = MIMEText(open(‘跑车.jpg’, ‘rb’).read(), ‘base64’, ‘utf-8’)
# 告知浏览器或邮件服务器这是字节流,浏览器处理字节流的默认方式为下载
attachment[‘Content-Type’] = ‘application/octet-stream’
# 此部分主要是告知浏览器或邮件服务器这是一个附件,名字叫做xxxxx,
# 这个文件名不要用中文,不同邮箱对中文的对待形式不同
attachment[‘Content-Disposition’] = ‘attachment;filename=”car.jpg”‘
msg.attach(attachment)
(3)邮件构造完成,可以发送邮件,使用最开始连通的服务器调用sendmail方法。sendemail(from_addr, to_addrs, msg.as_string())
from_addr:发件人邮箱地址;
to_addrs:收件人邮箱地址,可以传入存放了多个收件人地址的列表;
msg:发送的消息。
server.sendmail(sendAddress,[‘xxx@qq.com’],msg.as_string())
print(‘发送成功’)
注意: 邮件内容不规范会被邮箱服务器拦截,发送失败。
详情请根据报错原因查看此链接
service.mail.qq.com/cgi-bin/hel…