python发送邮件和附件:Python操作Exchange邮箱发送邮件
python发送邮件和附件:Python操作Exchange邮箱发送邮件
安装包pip install Exchangelib
代码
下面是使用outlook邮箱给QQ邮箱发送消息和附件的案例:
# -*- coding: utf-8 -*-
import urllib3
import logging
from exchangelib import Credentials Account DELEGATE Configuration NTLM Message Mailbox HTMLBody \
FileAttachment Build Version BASIC
from exchangelib.Protocol import BaseProtocol NoVerifyHTTPAdapter
from exchangelib.errors import ErrorNonExistentMailbox UnauthorizedError
from django.conf import settings
Outlook_ADMIN_USERNAME = getattr(settings "OUTLOOK_ADMIN_USERNAME")
OUTLOOK_ADMIN_PASSWORD = getattr(settings "OUTLOOK_ADMIN_PASSWORD")
OUTLOOK_SERVER = getattr(settings "OUTLOOK_SERVER")
OUTLOOK_EXCHANGE_VERSION = getattr(settings "OUTLOOK_EXCHANGE_VERSION")
class OutlookServer:
"""
为了兼容outlook邮箱,对outlook做了简单的封装。
"""
def __init__(self):
# Tell exchangelib to use this adapter class instead of the default
# exchangelib provides a sample adapter which ignores TLS validation errors.
# Use at own risk. NTML is NT LAN Manager.
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
urllib3.disable_warnings()
self.username = OUTLOOK_ADMIN_USERNAME
self.password = OUTLOOK_ADMIN_PASSWORD
self.server = OUTLOOK_SERVER
self.exchange_version = OUTLOOK_EXCHANGE_VERSION
version = Version(
build=Build(*map(int self.exchange_version.split('.')))
)
credentials = Credentials(
self.username.split("@")[0] self.password
)
config = Configuration(
server=self.server credentials=credentials version=version auth_type=NTLM
)
self.account = Account(self.username config=config access_type=DELEGATE)
@property
def is_outlook_address(self):
try:
self.account.calendar.id
except (ErrorNonExistentMailbox UnauthorizedError):
return False
except Exception as e:
logging.exception(e)
return False
else:
return True
def send_email(self recipients subject body attach_file_path_list=[] attach_file_dict={} pic_list=[]):
"""
:param recipients: 收件人/收件人列表
:param subject: 邮件标题
:param body: 邮件正文
:param attach_file_path_list: 附件列表(文件路径形式,例如 ["/data/pdf/a.pdf"] )
:param attach_file_dict: 附件列表(文件二进制内容,list,例如 ["/data/pdf/a.pdf"],附件名称自动取文件名称)
:param pic_list: 图片列表(图片二进制内容,dict,例如 {"附件1.pdf" "231234wewqe" "附件2.rar" "231234wewqe"} )
:return:
"""
if isinstance(recipients str):
recipients = [recipients]
msg = Message(
account=self.account
subject=subject
body=HTMLBody(body)
to_recipients=[Mailbox(email_address=recipient) for recipient in recipients]
)
# 文件附件
for file_path in attach_file_path_list:
with open(file_path 'rb') as f:
attachment_name = file_path.split("/")[-1]
file_attachment = FileAttachment(
name=attachment_name
content=f.read()
)
msg.attach(file_attachment)
for name content in attach_file_dict.items():
file_attachment = FileAttachment(name=name content=content)
msg.attach(file_attachment)
msg.send_and_save()
if __name__ == "__main__":
# outlook_server = OutlookServer("xxxxxx@outlook.com" "" "outlook.office365.com" "15.1")
outlook_server = OutlookServer()
if outlook_server.is_outlook_address:
outlook_server.send_email("xxxxxxx@qq.com" "消息发送" "调试调用发送邮件") # 测试调用发送邮件
else:
print("Error not outlook server")
当然,除了发送邮件消息和附件之外,还可以抄送,密送给某人。只需要修改不同的参数即可
msg = Message(
folder=self.account.sent
account=self.account
subject=subject
body=HTMLBody(body)
to_recipients=to_recipients # 要发送的收件人邮箱地址列表
cc_recipients=cc_recipients # 要发送的抄送人邮箱地址列表
bcc_recipients=bcc_recipients # 要发送的密送人邮箱地址列表
)
注意
注意,不同版本的Exchange有不同版本的version,可以在Exchange管理后台查看
注意:因为版本的不同很可能导致诸多问题,小编在客户那遇到了Exchange2007版本的,踩了不少坑,消息能发送,附件却发送不了,等等,大家使用中有遇到问题可关注小编,助你一臂之力