Python 调用 Outlook 发送邮件过程解析


Posted in Python onAugust 08, 2019

微软 Office 提供基于 COM 接口的编程。Python 通过 pywin32 可以方便地调用各组件。如果下载和安装 pywin32 有困难,可以到 Sourceforge 的镜像网摘查找合适的版本。

单一账号

import win32com.client as win32
def send_mail():
  outlook = win32.Dispatch('Outlook.Application')
  mail_item = outlook.CreateItem(0) # 0: olMailItem
  mail_item.Recipients.Add('someone@qq.com')
  mail_item.Subject = 'Mail Test'
  mail_item.BodyFormat = 2     # 2: Html format
  mail_item.HTMLBody = '''
    <H2>Hello, This is a test mail.</H2>
    Hello Guys. 
    '''
  mail_item.Send()
if __name__ == '__main__':
  send_mail()

多账号发送邮件

如果 Outlook 有多个账号,需要选择账号发送邮件,需要在代码中对账号进行判断,代码如下:

def send_mail():
  outlook_app = win32.Dispatch('Outlook.Application')
  # choose sender account
  send_account = None
  for account in outlook_app.Session.Accounts:
    if account.DisplayName == 'sender@hotmail.com':
      send_account = account
      break
  mail_item = outlook_app.CreateItem(0)  # 0: olMailItem
  # mail_item.SendUsingAccount = send_account not working
  # the following statement performs the function instead
  mail_item._oleobj_.Invoke(*(64209, 0, 8, 0, send_account))
  mail_item.Recipients.Add('receipient@qq.com')
  mail_item.Subject = 'Test sending using particular account'
  mail_item.BodyFormat = 2  # 2: Html format
  mail_item.HTMLBody = '''
    <H2>Hello, This is a test mail.</H2>
    Hello Guys. 
    '''
  mail_item.Send()
if __name__ == '__main__':
  send_mail()

这里有点黑魔法,直接设置 mail_item.SendUsingAccount 不会起作用,返回值是 None, 永远从第一个邮箱账号发送邮件,我使用的是 Office 365 版。需要调用 _oleobj_.Invoke() 方法。后面列出了参考链接。

本质上,这种方法是调用 COM 组件,可以查询微软的开发帮助了解相关对象的属性和方法,比如我想知道 Account 的细节,就特意参考了下面这篇帮助:https://docs.microsoft.com/zh-cn/office/vba/api/outlook.account 。COM 编程与语言无关。另外可以在 Outlook 中 ALT + F11,进入 VBE 环境,然后 F2 进入对象浏览器界面查看比如下面的界面显示了 Account 的属性和方法:

Python 调用 Outlook 发送邮件过程解析

关于调试

python 作为动态语言,通过 Debug 获取 COM 对象信息并不是很方便,比如下面代码:

import win32com.client as win32
def print_outlook_accounts():
  outlook_app = win32.Dispatch('Outlook.Application')
  for account in outlook_app.Session.Accounts:
    print (account.DeliveryStore.DisplayName)
if __name__ == '__main__':
  send_mail()

设置断点的调试界面:

Python 调用 Outlook 发送邮件过程解析

我们只知道 account 是一个 COM Object,account 包含的信息很多都是 unknown 的。碰到这种情况,我一般用 C# 或者 VBA 编写代码进行调试。如果我需要详细了解 account 的属性和方法,在 Office 的任何组件中,比如 Excel,写一段下面的代码:

Public Sub Print_Outlook_Accounts()
  ' 工具 -> 引用:添加 Microsoft Outook Object Library 引用  
  Dim outlookApp As New Outlook.Application
  Dim accounts As Outlook.accounts  
  Set accounts = outlookApp.Session.accounts  
  Dim account As Outlook.account
  For Each account In accounts
    Debug.Print account.DisplayName
  Next
End Sub

显示出监视窗口,设置断点,获取 accounts 信息:

Python 调用 Outlook 发送邮件过程解析

在监视窗口添加变量 accounts:

Python 调用 Outlook 发送邮件过程解析

展开:

Python 调用 Outlook 发送邮件过程解析

Item 1 和 Item 2 表示有两个账号,现在我们想看到 Item 2 的账号信息,将 Item 2 展开:

Python 调用 Outlook 发送邮件过程解析

DeliveryStore 属性也包含 account 的信息,可以展开查看。

参考

SendUsingAccount Does Not Work in Outlook 2010, possible bug?

python win32com outlook 2013 SendUsingAccount return exception

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的MongoDB基本操作:连接、查询实例
Feb 13 Python
Python的Django框架中URLconf相关的一些技巧整理
Jul 18 Python
使用Python来开发Markdown脚本扩展的实例分享
Mar 04 Python
详解Python操作RabbitMQ服务器消息队列的远程结果返回
Jun 30 Python
python表格存取的方法
Mar 07 Python
Python向Excel中插入图片的简单实现方法
Apr 24 Python
浅谈解除装饰器作用(python3新增)
Oct 15 Python
Python3内置模块pprint让打印比print更美观详解
Jun 02 Python
python实现文件的备份流程详解
Jun 18 Python
简单了解python单例模式的几种写法
Jul 01 Python
python cv2在验证码识别中应用实例解析
Dec 25 Python
教你怎么用Python selenium操作浏览器对象的基础API
Jun 23 Python
python判断自身是否正在运行的方法
Aug 08 #Python
Python 日期区间处理 (本周本月上周上月...)
Aug 08 #Python
python各类经纬度转换的实例代码
Aug 08 #Python
Python3.0 实现决策树算法的流程
Aug 08 #Python
Python使用ffmpy将amr格式的音频转化为mp3格式的例子
Aug 08 #Python
Django rest framework jwt的使用方法详解
Aug 08 #Python
使用Python实现文字转语音并生成wav文件的例子
Aug 08 #Python
You might like
浅谈apache和nginx的rewrite的区别
2013/02/22 PHP
CI(CodeIgniter)框架中的增删改查操作
2014/06/10 PHP
异步加载技术实现当滚动条到最底部的瀑布流效果
2014/09/16 PHP
php获取服务器操作系统相关信息的方法
2016/10/08 PHP
Javascript new关键字的玄机 以及其它
2010/08/25 Javascript
SharePoint 客户端对象模型 (一) ECMA Script
2011/05/22 Javascript
javascript 实现键盘上下左右功能的小例子
2013/09/15 Javascript
基于jQuery实现弹幕APP
2017/02/10 Javascript
JavaScript 函数的定义-调用、注意事项
2017/04/16 Javascript
慕课网题目之js实现抽奖系统功能
2017/09/19 Javascript
微信小程序使用map组件实现获取定位城市天气或者指定城市天气数据功能
2019/01/22 Javascript
Webpack4+Babel7+ES6兼容IE8的实现
2019/04/10 Javascript
Vee-validate 父组件获取子组件表单校验结果的实例代码
2019/05/20 Javascript
JS中的算法与数据结构之字典(Dictionary)实例详解
2019/08/20 Javascript
es6函数中的作用域实例分析
2020/04/18 Javascript
通过angular CDK实现页面元素拖放的步骤详解
2020/07/01 Javascript
微信小程序拖拽排序列表的示例代码
2020/07/08 Javascript
Python中函数的参数定义和可变参数用法实例分析
2015/06/04 Python
在Django的模型中执行原始SQL查询的方法
2015/07/21 Python
Python简单检测文本类型的2种方法【基于文件头及cchardet库】
2016/09/18 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
python分别打包出32位和64位应用程序
2020/02/18 Python
基于OpenCV的网络实时视频流传输的实现
2020/11/15 Python
python Scrapy爬虫框架的使用
2021/01/21 Python
Python实现区域填充的示例代码
2021/02/03 Python
CSS实现半透明边框与多重边框的场景分析
2019/11/13 HTML / CSS
html5中localStorage本地存储的简单使用
2017/06/16 HTML / CSS
HTML5 Canvas画线技巧——实现绘制一个像素宽的细线
2013/08/02 HTML / CSS
HTML5实现文件断点续传的方法
2017/01/04 HTML / CSS
美国礼品卡商城: Gift Card Mall
2017/08/25 全球购物
上海天奕面试题笔试题
2015/04/19 面试题
《雾凇》教学反思
2014/02/17 职场文书
2014年节能减排工作总结
2014/12/06 职场文书
2015年语言文字工作总结
2015/07/23 职场文书
土木工程生产实习心得体会
2016/01/22 职场文书
受欢迎的自荐信,就这么写!
2019/04/19 职场文书