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的Django框架中forms表单类的使用方法详解
Jun 21 Python
深入浅析Python中join 和 split详解(推荐)
Jun 30 Python
Python之Scrapy爬虫框架安装及简单使用详解
Dec 22 Python
python做量化投资系列之比特币初始配置
Jan 23 Python
python利用百度AI实现文字识别功能
Nov 27 Python
Python英文文本分词(无空格)模块wordninja的使用实例
Feb 20 Python
Django实现跨域的2种方法
Jul 31 Python
Python Scrapy框架第一个入门程序示例
Feb 05 Python
Python接口开发实现步骤详解
Apr 26 Python
PyCharm最新激活码PyCharm2020.2.3有效
Nov 18 Python
python全栈开发语法总结
Nov 22 Python
Python基础之元类详解
Apr 29 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开发大型项目的一点经验
2006/10/09 PHP
php中的注释、变量、数组、常量、函数应用介绍
2012/11/16 PHP
PHP5.3安装Zend Guard Loader图文教程
2014/09/29 PHP
php中的常用魔术方法汇总
2016/02/14 PHP
thinkphp3.x中session方法的用法分析
2016/05/20 PHP
php微信公众号开发之二级菜单
2018/10/20 PHP
PHP 超级全局变量相关总结
2020/06/30 PHP
PHP快速导出百万级数据到CSV或者EXCEL文件
2020/11/27 PHP
jquery 插件 人性化的消息显示
2008/01/21 Javascript
基于jquery的滚动新闻列表
2010/06/19 Javascript
javascript克隆对象深度介绍
2012/11/20 Javascript
基于KMP算法JavaScript的实现方法分析
2013/05/03 Javascript
js限制文本框只能输入整数或者带小数点的数字
2015/04/27 Javascript
详解JavaScript中数组的相关知识
2015/07/29 Javascript
jQuery Validate 校验多个相同name的方法
2017/05/18 jQuery
AngularJS中下拉框的基本用法示例
2017/10/11 Javascript
angular写一个列表的选择全选交互组件的示例
2018/01/22 Javascript
vue 2.x 中axios 封装的get 和post方法
2018/02/28 Javascript
React为 Vue 引入容器组件和展示组件的教程详解
2018/05/03 Javascript
浏览器JavaScript调试功能无法使用解决方案
2020/09/18 Javascript
python中使用正则表达式的连接符示例代码
2017/10/10 Python
Python内置模块ConfigParser实现配置读写功能的方法
2018/02/12 Python
对python自动生成接口测试的示例讲解
2018/11/30 Python
Python中的 enum 模块源码详析
2019/01/09 Python
关于Python中的向量相加和numpy中的向量相加效率对比
2019/08/26 Python
Python 3.6打包成EXE可执行程序的实现
2019/10/18 Python
python实现while循环打印星星的四种形状
2019/11/23 Python
基于Python3.7.1无法导入Numpy的解决方式
2020/03/09 Python
Python 读取xml数据,cv2裁剪图片实例
2020/03/10 Python
酒店员工职业生涯规划
2014/02/25 职场文书
厨房管理计划书
2014/04/27 职场文书
2014年小学班主任工作总结
2014/11/08 职场文书
2015年教师节感恩寄语
2015/03/23 职场文书
旅行社计调工作总结
2015/08/12 职场文书
python 实现定时任务的四种方式
2021/04/01 Python
idea下配置tomcat避坑详解
2022/04/12 Servers