import smtplib
import poplib
import imaplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
‘‘‘
smtplib 用于邮件的发信动作
poplib/imaplib 用于邮件的收信动作
email 用于解析构建邮件内容
email.mime.text 构建邮件正文
email.header 构建邮件头
mail.mime.multipart 构建可包含附件的邮件
‘‘‘
class Operate_Mail:
# 此函数通过使用smtplib实现发送邮件
def send_email_by_smtp(self):
# smtp服务器地址,也可以直接是IP地址;
smtp_server_host = "smtp.abc.com"
# smtp服务器监听的端口;
smtp_server_port = 25
# 用于发送邮件的邮箱;
sender_email_address = "sender@abc.com"
# 用于发送邮件的邮箱的密码;
sender_email_password = "123456"
# 要发往的邮箱;
receiver_email = "receiver@abc.com"
# 要发送的邮件主题;
message_subject = "Python smtp测试邮件"
# 要发送的邮件内容;
message_context = "这是一封通过Python smtp发送的测试邮件..."
# 构建邮件:message
# # 方式1.创建一个不带附件的实例,MIMEText();
# # 构建邮箱正文内容,第一个参数为内容,第二个参数为格式(plain为纯文本),第三个参数为编码;
# # 如果要发送html,请将plain改为html
# message = MIMEText(message_context, ‘plain‘, ‘utf-8‘)
# # 设置发件人(声称的)
# message["From"] = Header(sender_email_address, "utf-8")
# # 设置收件人(声称的)
# message["To"] = Header(receiver_email, "utf-8")
# # 设置邮件主题
# message["Subject"] = Header(message_subject,"utf-8")
# 方式2.创建一个可带附件的实例,MIMEMultipart();
message = MIMEMultipart()
message[‘From‘] = Header(sender_email_address, ‘utf-8‘)
message[‘To‘] = Header(receiver_email, ‘utf-8‘)
message[‘Subject‘] = Header(message_subject, ‘utf-8‘)
# 邮件正文内容
message.attach(MIMEText(message_context, ‘plain‘, ‘utf-8‘))
# 构造附件,传送当前目录下的 mail.py 文件;
att1 = MIMEText(open(‘mail.py‘, ‘rb‘).read(), ‘base64‘, ‘utf-8‘)
att1["Content-Type"] = ‘application/octet-stream‘
# 这里的filename是邮件中显示什么名字;
att1["Content-Disposition"] = ‘attachment; filename="mail.py"‘
message.attach(att1)
# 连接smtp服务器,如果没有使用SSL,将SMTP_SSL()改成SMTP()即可;
# email_client = smtplib.SMTP_SSL(smtp_server_host, smtp_server_port)
email_client = smtplib.SMTP(smtp_server_host, smtp_server_port)
try:
# 验证邮箱及密码是否正确
email_client.login(sender_email_address, sender_email_password)
print("smtp----login success, now will send an email to {receiver_email}")
except:
print("smtp----sorry, username or password not correct or another problem occur")
else:
# 发送邮件
email_client.sendmail(sender_email_address, receiver_email, message.as_string())
print(f"smtp----send email to {receiver_email} finish")
finally:
# 关闭连接
email_client.close()
# 此函数通过使用poplib实现接收邮件
def recv_email_by_pop3(self):
# pop服务器地址,也可以直接是IP地址;
pop_server_host = "pop3.abc.com"
# pop服务器的监听端口;
pop_server_port = 995
# 要进行邮件接收的邮箱;
email_address = "autotest@abc.com"
# 要进行邮件接收的邮箱的密码;
email_password = "123456"
try:
# 连接pop服务器,如果没有使用SSL,将POP3_SSL()改成POP3()即可;
email_server = poplib.POP3_SSL(host=pop_server_host, port=pop_server_port, timeout=10)
print("pop3----connect server success, now will check username")
except:
print("pop3----sorry the given email server address connect time out")
exit(1)
try:
# 验证邮箱是否存在
email_server.user(email_address)
print("pop3----username exist, now will check password")
except:
print("pop3----sorry the given email address seem do not exist")
exit(1)
try:
# 验证邮箱密码是否正确
email_server.pass_(email_password)
print("pop3----password correct,now will list email")
except:
print("pop3----sorry the given username seem do not correct")
exit(1)
# 邮箱中其收到的邮件的数量
email_count = len(email_server.list()[1])
# 通过retr(index)读取第index封邮件的内容:这里读取最后一封,也即最新收到的那一封邮件;
resp, lines, octets = email_server.retr(email_count)
# lines是邮件内容,列表形式使用join拼成一个byte变量;
email_content = b‘\r\n‘.join(lines)
# 再将邮件内容由byte转成str类型
email_content = email_content.decode()
print(email_content)
# 关闭连接
email_server.close()
# 此函数通过使用imaplib实现接收邮件
def recv_email_by_imap4(self):
# imap服务器地址,也可以直接是IP地址;
imap_server_host = "imap.abc.com"
# imap服务器的监听端口;
imap_server_port = 993
# 要进行邮件接收的邮箱;
email_address = "autotest@abc.com"
# 要进行邮件接收的邮箱的密码;
email_password = "123456"
try:
# 连接imap服务器,如果没有使用SSL,将IMAP4_SSL()改成IMAP4()即可;
email_server = imaplib.IMAP4_SSL(host=imap_server_host, port=imap_server_port)
print("imap4----connect server success, now will check username")
except:
print("imap4----sorry the given email server address connect time out")
exit(1)
try:
# 验证邮箱及密码是否正确
email_server.login(email_address,email_password)
print("imap4----username exist, now will check password")
except:
print("imap4----sorry the given email address or password seem do not correct")
exit(1)
# 选择邮箱中的一个文件夹:默认INBOX
email_server.select()
# 获取邮箱中其收到的邮件的数量:
# search方法在文件夹内搜索匹配的邮件;
# 参数1是字符集,None默认就是ASCII编码,参数2是查询条件,ALL就是查找全部,该函数返回的是字符数组(type,data);
# 其中data为返回的时匹配的邮件编号列表,邮件编号时按照升序且以空格分隔;
# 使用.split()将提取的邮件编号生产一个列表,然后使用len获取邮箱文件夹内的所有邮件数量;
email_count = len(email_server.search(None, ‘ALL‘)[1][0].split())
# 通过fetch(index)读取第index封邮件的内容:这里读取最后一封,也即最新收到的那一封邮件;
typ, email_content = email_server.fetch(f‘{email_count}‘.encode(), ‘(RFC822)‘)
# 提取有效邮件内容(byte类型)
b_email_content = email_content[0][1]
# 输入方式1.将邮件内容由byte转成str后输出,缺点:打印内容为未被解析的邮件内容;
# str_email_content = b_email_content.decode()
# print(str_email_content)
# 输入方式2.使用email模块解析邮件内容
import email
# 可以从bytes或string类型甚至文件中进行解析,返回<class ‘email.message.Message‘>;
msg = email.message_from_bytes(b_email_content)
# msg = email.message_from_string(str_email_content)
# print(msg)
# 2.1 获取邮件头部信息(邮件主题/发件人/收件人等...);使用get方法或者索引方式;
subject = msg[‘Subject‘]
# print(subject)
# 判断邮件主题是否包含中文,当包含中文时进行解码;
subject_list = email.header.decode_header(subject)
# print(subject_list)
if typ:=subject_list[0][1]:
print(f‘邮件主题:{subject_list[0][0].decode(typ)}‘)
else:
print(f‘邮件主题:{subject}‘)
# 2.2 获取信体部分;
# walk()函数能历遍邮件所有部分,然后再使用is_multipart()函数来判断内容是否有用,打印出有用内容;
# 最后用get_payload(decode=True).decode(‘utf-8‘)解码并且打印到控制台;
# 通常这个循环有两次,第一次是单纯的字符串格式的,能在控制台显示出来的,第二次循环打印的是像HTML的格式;
attach_list = []
for part in msg.walk():
# is_multipart():如果消息由多个部分组成,则返回True;
if not part.is_multipart():
# 当邮件中有附件时decode(‘utf-8‘)报错;
v = part.get(‘content-disposition‘)
if v and v[0:len(‘attachment‘)] == ‘attachment‘:
attach_name = part.get_filename()
# 判断邮件附件名是否包含中文,当包含中文时进行解码;
attach_name_list =email.header.decode_header(attach_name)
# print(attach_name_list)
if typ:=attach_name_list[0][1]:
attach_list.append(attach_name_list[0][0].decode(typ))
else:
attach_list.append(attach_name)
else:
# 解码出文本内容,并输出;
print(part.get_payload(decode=True).decode(‘utf-8‘))
# 打印发现的邮件附件;
if attach_list:
print(f‘发现邮件附件: {attach_list}‘)
# 关闭select
email_server.close()
# 关闭连接
email_server.logout()
if __name__ == "__main__":
# 实例化
email_client = Operate_Mail()
# 调用通过smtp发送邮件的发送函数
# email_client.send_email_by_smtp()
# 调用通过pop3接收邮件的接收函数
# email_client.recv_email_by_pop3()
# 调用通过imap4接收邮件的接收函数
email_client.recv_email_by_imap4()
原文:https://www.cnblogs.com/Beavan/p/14470435.html