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实现打印螺旋矩阵功能的方法
Nov 21 Python
Python语言描述KNN算法与Kd树
Dec 13 Python
Python实现PS滤镜功能之波浪特效示例
Jan 26 Python
Python实现处理逆波兰表达式示例
Jul 30 Python
对python读取zip压缩文件里面的csv数据实例详解
Feb 08 Python
python浪漫表白源码
Apr 05 Python
python整合ffmpeg实现视频文件的批量转换
May 31 Python
详解将Pandas中的DataFrame类型转换成Numpy中array类型的三种方法
Jul 06 Python
Django 缓存配置Redis使用详解
Jul 23 Python
python RC4加密操作示例【测试可用】
Sep 26 Python
将tf.batch_matmul替换成tf.matmul的实现
Jun 18 Python
聊聊Python pandas 中loc函数的使用,及跟iloc的区别说明
Mar 03 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 301转向实现代码
2008/09/18 PHP
Fine Uploader文件上传组件应用介绍
2013/01/06 PHP
解析PHP多种序列化与反序列化的方法
2013/06/06 PHP
PHP实现HTML生成PDF文件的方法
2014/11/07 PHP
typecho插件编写教程(三):保存配置
2015/05/28 PHP
js实现浏览器的各种菜单命令比如打印、查看源文件等等
2013/10/24 Javascript
jquery 通过name快速取值示例
2014/01/24 Javascript
javascript异步编程的4种方法
2014/02/19 Javascript
js 弹出新页面避免被浏览器、ad拦截的一种新方法
2014/04/30 Javascript
node.js中的console.time方法使用说明
2014/12/09 Javascript
jQuery遍历DOM元素与节点方法详解
2016/04/14 Javascript
JS把内容动态插入到DIV的实现方法
2016/07/19 Javascript
AngularJS 中的数据源的循环输出
2017/10/12 Javascript
利用vue + koa2 + mockjs模拟数据的方法教程
2017/11/22 Javascript
快速解决brew安装特定版本flow的问题
2018/05/17 Javascript
一文了解Vue中的nextTick
2019/05/06 Javascript
详解可以用在VS Code中的正则表达式小技巧
2019/05/14 Javascript
[38:54]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第一场 11.28
2020/12/01 DOTA
Python实现的最近最少使用算法
2015/07/10 Python
ubuntu环境下python虚拟环境的安装过程
2018/01/07 Python
python使用sqlite3时游标使用方法
2018/03/13 Python
Python实现的拟合二元一次函数功能示例【基于scipy模块】
2018/05/15 Python
Python切片操作去除字符串首尾的空格
2019/04/22 Python
python3的url编码和解码,自定义gbk、utf-8的例子
2019/08/22 Python
python动态视频下载器的实现方法
2019/09/16 Python
python sklearn常用分类算法模型的调用
2019/10/16 Python
Python利用imshow制作自定义渐变填充柱状图(colorbar)
2020/12/10 Python
HTML5地理定位与第三方工具百度地图的应用
2016/11/17 HTML / CSS
初中生三年学习生活的自我评价
2013/11/03 职场文书
消防先进事迹材料
2014/02/10 职场文书
事业单位竞聘上岗实施方案
2014/03/28 职场文书
药品营销专业毕业生自荐信
2014/07/02 职场文书
党的群众路线教育实践活动通讯稿
2014/09/10 职场文书
党支部评议意见
2015/06/02 职场文书
煤矿安全学习心得体会
2016/01/18 职场文书
2016大学生暑期三下乡心得体会
2016/01/23 职场文书