Python--邮件处理

一、发送电子邮件

1.1、SMTP发送电子邮件

Python标准库提供了smtplib模块,用于实现SMTP协议,发送邮件。标准库还提供了email模块帮助我们构造邮件格式。
SMTP(Simple Mail Transfer Protocol,即简单邮件传输协议),是一组由源地址到目的地址传送邮件的规则,用来控制信件的中转方式。
Python的smtplib提供了一种发送电子邮件的方便途径,它会SMTP协议进行了简单的封装。

Python创建SMTP对象的语法为:

smtpObj = smtplib.SMTP([host [,port [,local_hostname]]])

参数说明:

  • host:SMTP服务器主机,是可选参数。可以指定主机的IP地址或者域名,如:smtp.exmail.qq.com;
  • port:如果提供了host参数,就需要指定SMTP服务使用的端口号,一般情况下SMTP的端口号为25;
  • local_hostname:如果SMTP在自己的本机上,则只需要指定服务器地址为localhost即可;

Python SMTP对象使用sendmail方法发送邮件,语法如下:

SMTP.sendmail(from_addr,to_addrs,msg[,mail_options,rcpt_options])

参数说明:

  • from_addr:邮件发送地址;
  • to_addr:字符串列表,邮件接收地址;
  • msg:发送消息,一般使用字符串

预备工作:开启SMTP和POP3服务,获取授权码

使用QQ邮箱发送邮件需要开启SMTP服务和POP3服务,SMTP协议用于发送邮件,POP3协议用于接收邮件,授权码用于连接到服务器。

1、登录邮箱->设置->账户

在这里插入图片描述

2、按要求发送短信验证,开启服务

在这里插入图片描述

3、开启服务之后就得到了授权码,此授权码不需要记,忘记了就关闭服务再开启服务即可

在这里插入图片描述

4、开启服务转态,如下图

在这里插入图片描述

import smtplib
from email.mime.text import MIMEText
from email.header import Header

#邮箱用户名
sender = "1178277540@qq.com"
#邮箱授权码
license = "ducdjgclcisahjdc"
#收件人
receicer = ["364336543@qq.com","wang_jc@126.com"]

#邮件正文
message = MIMEText("赳赳老秦,共赴国难!","plain","utf-8")

#发件人显式的名字
message["From"] = Header("嬴师隰","utf-8")

#收件人显式的名字
message["To"] = Header("嬴渠梁","utf-8")

#邮件标题
message["Subject"] = "一统天下"

try:
    smtp = smtplib.SMTP_SSL("smtp.qq.com",465)
    #登录
    smtp.login(sender,license)
    #发送
    smtp.sendmail(sender,receicer,message.as_string())
    print("邮件已发送")
except smtplib.SMTPException as e:
    print("Error! 发送失败",e)

在这里插入图片描述


1.2、发送HTML格式的电子邮件

发送HTML格式的邮件,只要在使用MIMEText函数构造邮件消息体的时候将第二个参数指定格式为“html”即可。

import smtplib
from email.mime.text import MIMEText
from email.header import Header

#邮箱用户名
sender = "1178277540@qq.com"
#邮箱授权码
license = "ducdjgclcisahjdc"
#收件人
receicer = ["364336543@qq.com","wang_jc@126.com"]

#邮件正文
mail_msg = """
<h1>秦孝公招贤令</h1>
<p>昔我缪公自岐雍之间,修德行武。东平晋乱,以河为界。西霸戎翟,广地千里。天子致伯,诸侯毕贺,为后世开业,甚光美。</br>
会往者历、躁、简公、出子子不宁,国家内忧,未遑外事,三晋夺我先君河西地,诸侯卑秦,丑莫大焉。</br>
献公即位,镇抚边境,徙治栎阳,且欲东伐,复缪公之故地,修缪公之政令。寡人思念先君之意,常痛于心。宾客群臣有能出奇计强秦者,吾为尊官,与之分土。</p>
"""
message = MIMEText(mail_msg,"html","utf-8")

#发件人显式的名字
message["From"] = Header("嬴渠梁","utf-8")

#收件人显式的名字
message["To"] = Header("六国士子","utf-8")

#邮件标题
message["Subject"] = "幕贤强秦"

try:
    smtp = smtplib.SMTP_SSL("smtp.qq.com",465)
    #登录
    smtp.login(sender,license)
    #发送
    smtp.sendmail(sender,receicer,message.as_string())
    print("邮件已发送")
except smtplib.SMTPException as e:
    print("Error! 发送失败",e)


在这里插入图片描述


1.3、发送带附件的邮件

附件其实就是另一种格式的MIME,所以在构造邮件消息体的时候需要使用MIMEMultipart来构造复合类型的消息体,然后把文本和附件一个一个地加进去。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

#邮箱用户名
sender = "1178277540@qq.com"
#邮箱授权码
license = "ducdjgclcisahjdc"
#收件人
receicer = ["364336543@qq.com","wang_jc@126.com"]

#指定消息体使用复合类型
message = MIMEMultipart()

#邮件正文
mail_msg = """
<h1>秦孝公招贤令</h1>
<p>昔我缪公自岐雍之间,修德行武。东平晋乱,以河为界。西霸戎翟,广地千里。天子致伯,诸侯毕贺,为后世开业,甚光美。</br>
会往者历、躁、简公、出子子不宁,国家内忧,未遑外事,三晋夺我先君河西地,诸侯卑秦,丑莫大焉。</br>
献公即位,镇抚边境,徙治栎阳,且欲东伐,复缪公之故地,修缪公之政令。寡人思念先君之意,常痛于心。宾客群臣有能出奇计强秦者,吾为尊官,与之分土。</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="main.py"'
message.attach(attached_file)

#发件人显式的名字
message["From"] = Header("嬴渠梁","utf-8")

#收件人显式的名字
message["To"] = Header("六国士子","utf-8")

#邮件标题
message["Subject"] = "一统天下"

try:
    smtp = smtplib.SMTP_SSL("smtp.qq.com",465)
    #登录
    smtp.login(sender,license)
    #发送
    smtp.sendmail(sender,receicer,message.as_string())
    print("邮件已发送")
except smtplib.SMTPException as e:
    print("Error! 发送失败",e)


在这里插入图片描述


1.4、发送图片

我们都知道HTML网页可以嵌入诸如图片、视频等元素,自然在HTML格式的邮件中也可以嵌入这些内容,但是效果不好,因为大部分的邮件客户端和服务商都会屏蔽邮件正文的外部资源,像网页中的图片或者视频、音频等都是外部资源。

如果我们需要发送图片,只需把图片作为附件添加到邮件消息体中,然后在HTML格式的正文中使用src=cid:img1格式嵌入即可。

import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.header import Header

#邮箱用户名
sender = "1178277540@qq.com"
#邮箱授权码
license = "ducdjgclcisahjdc"
#收件人
receicer = ["364336543@qq.com","wang_jc@126.com"]

#指定消息体使用复合类型
message = MIMEMultipart("related")

#邮件正文
msg_content = MIMEMultipart("alternative")

mail_msg = """
<h1>秦孝公招贤令</h1>
<p>昔我缪公自岐雍之间,修德行武。东平晋乱,以河为界。西霸戎翟,广地千里。天子致伯,诸侯毕贺,为后世开业,甚光美。</br>
会往者历、躁、简公、出子子不宁,国家内忧,未遑外事,三晋夺我先君河西地,诸侯卑秦,丑莫大焉。</br>
献公即位,镇抚边境,徙治栎阳,且欲东伐,复缪公之故地,修缪公之政令。寡人思念先君之意,常痛于心。宾客群臣有能出奇计强秦者,吾为尊官,与之分土。</p>
"""

msg_content.attach(MIMEText(mail_msg,"html","utf-8"))
message.attach(msg_content)

#添加图片
with open("winterfall.jpg","rb") as f:
    img1 = MIMEImage(f.read())

#定义资源的名字为img1
img1.add_header("Contend-ID","img1")
message.attach(img1)

#发件人显式的名字
message["From"] = Header("嬴渠梁","utf-8")
#收件人显式的名字
message["To"] = Header("六国士子","utf-8")
#邮件标题
message["Subject"] = "一统天下"

try:
    smtp = smtplib.SMTP_SSL("smtp.qq.com",465)
    #登录
    smtp.login(sender,license)
    #发送
    smtp.sendmail(sender,receicer,message.as_string())
    print("邮件已发送")
except smtplib.SMTPException as e:
    print("Error! 发送失败",e)


在这里插入图片描述


二、接收电子邮件

接收邮件有两种常用的协议:POP3和IMAP协议

POP3协议:POP3协议(Post Office Protocol-Version 3,即邮局协议版本3)允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等)不会反馈到服务器上,比如通过客户端收取了邮箱中的3封邮件并移动到其它文件夹,邮件服务器上的这些邮件不会被同时移动。

IMAP协议:IMAP协议(Internet Mail Acess Protocol,即Internet邮件访问协议)提供Webmail与电子邮件客户端之间的双向通信,任何在客户端做的改变都会同步到服务器上。在客户端对邮件进行了操作,服务器上的邮件也会进行相应的操作。

同时,IMAP协议像POP3协议一样,提供了方便的邮件下载服务,让用户能够进行离线阅读。IMAP协议提供的摘要浏览功能可以让你在阅读完所有的邮件信息(到达时间、主题、发件人、大小等)后才作出是否下载的决定。此外,IMAP协议能更好地支持在多个不同设备上随时访问新邮件的功能。

2.1、使用POP3协议下载邮件

import poplib
from email.parser import Parser

#登录邮箱的用户名
username = "1178277540@qq.com"
#登录邮箱的密码
password = "ducdjgclcisahjdc"

#连接邮箱服务器
pop_server = poplib.POP3_SSL("pop.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)
print(msg)
#可以根据邮件索引号直接从服务器删除邮件
pop_server.dele(index)
#关闭连接
pop_server.quit()

2.2、使用IMAP协议下载邮件

import imaplib
import email

#登录邮箱的用户名
username = "1178277540@qq.com"
#登录邮箱的密码
password = "ducdjgclcisahjdc"

#连接邮箱服务器
imap_server = imaplib.IMAP4_SSL("imap.qq.com",993)

#登录邮箱服务器
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 Header
from email.utils import parseaddr

#登录邮箱的用户名
username = "1178277540@qq.com"
#登录邮箱的密码
password = "ducdjgclcisahjdc"

#连接邮箱服务器
pop_server = poplib.POP3_SSL("pop.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)
print(msg)
#可以根据邮件索引号直接从服务器删除邮件
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_from_addr)

subject = decode_email(msg.get("Subject",""))
print("主题","")

#递归解析邮件
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("Attachement",content_type)


decode_mime(msg)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝勒里恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值