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中的推导式使用详解
Jun 03 Python
听歌识曲--用python实现一个音乐检索器的功能
Nov 15 Python
Python 含参构造函数实例详解
May 25 Python
python模块之paramiko实例代码
Jan 31 Python
解决python写入mysql中datetime类型遇到的问题
Jun 21 Python
python对list中的每个元素进行某种操作的方法
Jun 29 Python
selenium+python实现1688网站验证码图片的截取功能
Aug 14 Python
pygame游戏之旅 添加icon和bgm音效的方法
Nov 21 Python
对python条件表达式的四种实现方法小结
Jan 30 Python
Anaconda 查看、创建、管理和使用python环境的方法
Dec 03 Python
python实现坦克大战
Apr 24 Python
Pycharm github配置实现过程图解
Oct 13 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使用number_format函数截取小数的方法分析
2016/05/27 PHP
PHP+MySQL存储数据常见中文乱码问题小结
2016/06/13 PHP
Laravel5.7框架安装与使用学习笔记图文详解
2019/04/02 PHP
javascript 鼠标滚轮事件
2009/04/09 Javascript
jQuery操作Select的Option上下移动及移除添加等等
2013/11/18 Javascript
jQuery学习笔记之基础中的基础
2015/01/19 Javascript
JS实现在页面随时自定义背景颜色的方法
2015/02/27 Javascript
javascript实现信息增删改查的方法
2015/07/25 Javascript
Bootstrap CSS组件之面包屑导航(breadcrumb)
2016/12/17 Javascript
vue2.0多条件搜索组件使用详解
2020/03/26 Javascript
Nodejs实现文件上传的示例代码
2017/09/26 NodeJs
ng-zorro-antd 入门初体验
2018/12/03 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
2019/08/01 Javascript
jQuery中DOM常见操作实例小结
2019/08/01 jQuery
LayUI动态设置checkbox不显示的解决方法
2019/09/02 Javascript
Vue搭建后台系统需要注意的问题
2019/11/08 Javascript
vue倒计时刷新页面不会从头开始的解决方法
2020/03/03 Javascript
js实现鼠标拖曳效果
2020/12/30 Javascript
[14:25]教你分分钟做大人:主宰(HEROS)
2014/12/08 DOTA
[01:15:15]VG VS EG Supermajor小组赛B组胜者组第一轮 BO3第二场 6.2
2018/06/03 DOTA
Python中偏函数用法示例
2018/06/07 Python
python中强大的format函数实例详解
2018/12/05 Python
pandas DataFrame 删除重复的行的实现方法
2019/01/29 Python
python内存动态分配过程详解
2019/07/15 Python
pandas通过字典生成dataframe的方法步骤
2019/07/23 Python
python创建属于自己的单词词库 便于背单词
2019/07/30 Python
文科生自我鉴定
2014/02/15 职场文书
荷叶母亲教学反思
2014/04/30 职场文书
土建工程师岗位职责
2014/06/10 职场文书
2014年九一八事变演讲稿
2014/09/14 职场文书
2014最新党员批评与自我批评材料
2014/09/24 职场文书
2014年专项整治工作总结
2014/11/17 职场文书
德能勤绩廉个人总结
2015/02/14 职场文书
MySQL 覆盖索引的优点
2021/05/19 MySQL
关于vue-router-link选择样式设置
2022/04/30 Vue.js
windows10 家庭版下FTP服务器搭建教程
2022/08/05 Servers