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使用mysqldb连接数据库操作方法示例详解
Dec 03 Python
Bottle框架中的装饰器类和描述符应用详解
Oct 28 Python
Python并发编程协程(Coroutine)之Gevent详解
Dec 27 Python
Python安装图文教程 Pycharm安装教程
Mar 27 Python
windows下安装Python的XlsxWriter模块方法
May 03 Python
浅谈DataFrame和SparkSql取值误区
Jun 09 Python
Python将多个list合并为1个list的方法
Jun 27 Python
Python中关键字global和nonlocal的区别详解
Sep 03 Python
python进阶之多线程对同一个全局变量的处理方法
Nov 09 Python
使用PYTHON解析Wireshark的PCAP文件方法
Jul 23 Python
Python学习笔记之函数的参数和返回值的使用
Nov 20 Python
Python实现曲线拟合的最小二乘法
Feb 19 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
php数组排序usort、uksort与sort函数用法
2014/11/17 PHP
PHP扩展模块memcached长连接使用方法分析
2014/12/24 PHP
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
PHP两个n位的二进制整数相加问题的解决
2018/08/26 PHP
在UpdatePanel内jquery easyui效果失效的解决方法
2010/04/11 Javascript
重载toString实现JS HashMap分析
2011/03/13 Javascript
JS实现匀速运动的代码实例
2013/11/29 Javascript
jquery将一个表单序列化为一个对象的方法
2013/12/02 Javascript
js控制浏览器全屏示例代码
2014/02/20 Javascript
跟我学习javascript的Date对象
2015/11/19 Javascript
FullCalendar日历插件应用之数据展现(一)
2015/12/23 Javascript
js老生常谈之this,constructor ,prototype全面解析
2016/04/05 Javascript
在线引用最新jquery文件的实现方法
2016/08/26 Javascript
JQuery中Ajax的操作完整例子
2017/03/07 Javascript
jQuery插件FusionCharts绘制的2D条状图效果【附demo源码】
2017/05/13 jQuery
webpack开发跨域问题解决办法
2017/08/03 Javascript
详解node nvm进行node多版本管理
2017/10/21 Javascript
详解React之key的使用和实践
2018/09/29 Javascript
vue在自定义组件中使用v-model进行数据绑定的方法
2019/03/25 Javascript
详解微信小程序-扫一扫 wx.scanCode() 扫码大变身
2019/04/30 Javascript
Vue路由的模块自动化与统一加载实现
2020/06/05 Javascript
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
Python中函数参数设置及使用的学习笔记
2016/05/03 Python
Python3 pywin32模块安装的详细步骤
2020/05/26 Python
简单总结CSS3中视窗单位Viewport的常见用法
2016/02/04 HTML / CSS
全世界最美丽的四星和五星级酒店预订:Prestigia.com
2017/11/15 全球购物
伦敦剧院门票:London Theatre Direct
2018/11/21 全球购物
Airbnb爱彼迎官网:成为爱彼迎房东,赚取收入
2019/03/14 全球购物
幼儿园保育员岗位职责
2014/04/13 职场文书
校庆标语集锦
2014/06/25 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
老公出轨后的保证书
2015/05/08 职场文书
JavaScript实现简单图片切换
2021/04/29 Javascript
python 制作一个gui界面的翻译工具
2021/05/14 Python
深入理解MySQL中MVCC与BufferPool缓存机制
2022/05/25 MySQL
nginx配置指令之server_name的具体使用
2022/08/14 Servers