1.发送电子邮件
1.1 SMTP发送电子邮件
smtplib模块用于实现SMTP协议发送邮件,email模块帮我们构造邮件格式。
SMTP:简单邮件传输协议,是一组由源地址到目的地址传送邮件的规则,用来控制邮件的中转方式
python创建SMTP对象的语法:
smtpObj = smtplib.SMTP([host,port,local_hostname)
host:SMTP服务器主机,可选参数
port:端口,一般为25
local_hostnane:如果SMTP在本机,指定localhost即可
SMTP对象使用sendmail方法发送邮件的语法:
SMTP.sendmail(from_addr,to_addrs,msg,mail_options,rcpt_options)
from_addr:邮件发送者地址
to_addrs:字符串列表,邮件发送地址
msg:发送消息,一般字符串
import smtplib
from email.mime.text import MIMEText
from email.header import Header
#邮箱用户名
sender = "1@qq.com"
#邮箱密码
password = "1"
#收件人无论是否一个收件人都必须是列表
receiver = ["2@qq.com"]
#邮件正文
message = MIMEText("这是测试邮件","plain","utf-8")
#发件人显式的名字
message["From"] = Header("python发送邮件","utf-8")
#收件人显式的名字
message["To"] = Header("python接收邮件","utf-8")
#邮件标题
message["Subject"] = "Python SMTP 发送邮件"
try:
#使用QQ邮箱发送
smtp = smtplib.SMTP_SSL("smtp.exmail.qq.com",465)
#登录
smtp.login(sender,password)
#发送
smtp.sendmail(sender,receiver,message.as_string())
print("邮件已发送")
except smtplib.SMTPException as e:
print("发送失败",e)
1.2 发送HTTP格式邮箱
HTTP格式的邮箱可以发送很丰富的内容,不仅仅是文本
import smtplib
from email.mime.text import MIMEText
from email.header import Header
#邮箱用户名
sender = "1@qq.com"
#邮箱密码
password = "1"
#收件人无论是否一个收件人都必须是列表
receiver = ["2@qq.com",]
#邮件正文
mail_msg = "<p>使用python发送邮件</p>"
#制定消息体使用HTML格式
message = MIMEText(mail_msg,"html","utf-8")
#发件人显式的名字
message["From"] = Header("python发送邮件","utf-8")
#收件人显式的名字
message["To"] = Header("python接收邮件","utf-8")
#邮件标题
message["Subject"] = "Python SMTP 发送邮件"
try:
#使用QQ邮箱发送
smtp = smtplib.SMTP_SSL("smtp.exmail.qq.com",465)
#登录
smtp.login(sender,password)
#发送
smtp.sendmail(sender,receiver,message.as_string())
print("邮件已发送")
except smtplib.SMTPException as e:
print("发送失败",e)
1.3 发送带附件的邮件
另一种格式的MIME,需要使用MIMEMultipart来构建复合类型消息体,然后把文本和附件加进去
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
#邮箱用户名
sender = "1@qq.com"
#邮箱密码
password = "1"
#收件人无论是否一个收件人都必须是列表
receiver = ["2@qq.com",]
#制定消息体使用复合类型
message = MIMEMultipart()
#邮件正文
mail_msg = "<p>使用python发送邮件</p>"
message.attach(MIMEText(mail_msg,"html","utf-8"))
#添加附件
attached_file = MIMEText(open(__file__,encoding="utf-8").read(),"base64","utf-8")
#吸顶附件的文件名可以和原先的文件名不一样
attached_file["Content-Disposition"] = 'attachment;filename="mail.py"'
message.attach(attached_file)
#发件人显式的名字
message["From"] = Header("python发送邮件","utf-8")
#收件人显式的名字
message["To"] = Header("python接收邮件","utf-8")
#邮件标题
message["Subject"] = "Python SMTP 发送邮件"
try:
#使用QQ邮箱发送
smtp = smtplib.SMTP_SSL("smtp.exmail.qq.com",465)
#登录
smtp.login(sender,password)
#发送
smtp.sendmail(sender,receiver,message.as_string())
print("邮件已发送")
except smtplib.SMTPException as e:
print("发送失败",e)
1.4 发送图片
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
#邮箱用户名
sender = "1@qq.com"
#邮箱密码
password = "1"
#收件人无论是否一个收件人都必须是列表
receiver = ["2@qq.com",]
#采用related定义内嵌资源的邮件体
message = MIMEMultipart("related")
#发件人显式的名字
message["From"] = Header("python发送邮件","utf-8")
#收件人显式的名字
message["To"] = Header("python接收邮件","utf-8")
#邮件标题
message["Subject"] = "Python SMTP 发送邮件"
#邮件正文
msg_content = MIMEMultipart("alternative")
mail_msg = "<p>使用python发送邮件</p>"
msg_content.attach(MIMEText(mail_msg,"html","utf-8"))
message.attach(msg_content)
#添加图片
with open("test.png","rb") as f:
img1 = MIMEImage(f.read())
#定义资源的名字为img1
img1.add_header("Content-ID","img1")
message.attach(img1)
try:
#使用QQ邮箱发送
smtp = smtplib.SMTP_SSL("smtp.exmail.qq.com",465)
#登录
smtp.login(sender,password)
#发送
smtp.sendmail(sender,receiver,message.as_string())
print("邮件已发送")
except smtplib.SMTPException as e:
print("发送失败",e)
关于multipart里面的参数,如下:
2.接收邮件
接收邮件有两种常用的协议:POP3和IMAP
POP3:允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作不会反馈到服务器上。
IMAP:提供下载功能,同事提供摘要浏览。另外还支持在不同设备上随时访问新邮件。
2.1 使用POP3下载邮件
import poplib
from email.parser import Parser
#登录邮箱的用户名
username = "1@qq.com"
#登录邮箱的密码
password = "111"
#连接邮箱服务器
pop_server = poplib.POP3_SSL("pop.exmail.qq.com",995)
#打印出邮箱服务器的欢迎文字
print(pop_server.getwelcome().decode("utf-8"))
#登录邮箱服务器
pop_server.user(username)
pop_server.pass_(password)
#打印出当前账号的状态,第一个返回值为邮件数,第二个返回值为占用空间
print("Server stat",pop_server.stat())
#获取所有邮件列表
resp,mails,octets = pop_server.list()
print(mails)
#获取最新的一封邮件(序号最大的),索引从1开始计算
index = len(mails)
resp,lines,octets = pop_server.retr(index)
msg_content = b"\r\n".join(lines).decode("utf-8")
#解析出邮件
msg = Parser().parsestr(msg_content)
#可以根据邮件索引号直接从服务器删除邮件
pop_server.dele(index)
#关闭连接
pop_server.quit()
2.2 使用IMAP协议下载邮件
import imaplib
import email
#登录邮箱的用户名
username = "1@qq.com"
#登录邮箱的密码
password = "111"
#连接邮箱服务器
imap_server = imaplib.IMAP4_SSL("pop.exmail.qq.com",995)
#登录邮箱服务器
imap_server.login(username,password)
print("============LOG================")
imap_server.print_log()
print("===============================")
#获取邮箱目录
resp,data = imap_server.list()
print(data)
#选择默认收件箱并打印邮件数量
res,data = imap_server.select("INBOX")
print(res,data)
print(data[0])
#获取最新的一封邮件
typ,lines = imap_server.fetch(data[0],"(RFC822)")
#解析出邮件
msg = email.message_from_string(lines[0][1].decode("utf-8"))
#关闭连接
imap_server.close()
2.3 解析邮件
解析邮件的过程正好和发送邮件相反
import poplib
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
#登录邮箱的用户名
username = "1@qq.com"
#登录邮箱的密码
password = "111"
#连接邮箱服务器
pop_server = poplib.POP3_SSL("pop.exmail.qq.com",995)
#打印出邮箱服务器的欢迎文字
print(pop_server.getwelcome().decode("utf-8"))
#登录邮箱服务器
pop_server.user(username)
pop_server.pass_(password)
#打印出当前账号的状态,第一个返回值为邮件数,第二个返回值为占用空间
print("Server stat",pop_server.stat())
#获取所有邮件列表
resp,mails,octets = pop_server.list()
print(mails)
#获取最新的一封邮件(序号最大的),索引从1开始计算
index = len(mails)
resp,lines,octets = pop_server.retr(index)
msg_content = b"\r\n".join(lines).decode("utf-8")
#解析出邮件
msg = Parser().parsestr(msg_content)
#可以根据邮件索引号直接从服务器删除邮件
pop_server.dele(index)
#关闭连接
pop_server.quit()
def decode_email(s):
if not s:
return ""
value,charset = decode_header(s)[0]
if charset:
value = value.decode(charset)
return value
#打印邮件的发件人、收件人和主题
mail_from = msg.get("From","")
hdr,mail_from_addr = parseaddr(mail_from)
mail_from_name = decode_email(hdr)
print("发件人",mail_from_name,mail_from_addr)
mail_to = msg.get("To","")
hdr,mail_to_addr = parseaddr(mail_to)
mail_to_name = decode_email(hdr)
print("收件人",mail_to_name,mail_to_addr)
subject = decode_email(msg.get("Subject",""))
print("主题",subject)
#递归解析邮件
def decode_mime(msg):
if msg.is_multipart():
parts = msg.get_payload()
for part in parts:
print(decode_mime(part))
else:
content_type = msg.get_content_type()
if content_type in ("text/plain","text/html"):
content = msg.get_payload(decode=True)
print(content)
else:
print("Attachment",content_type)
decode_mime(msg)