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中.py文件打包成exe可执行文件详解
Mar 22 Python
Python编程实现的图片识别功能示例
Aug 03 Python
python清除字符串前后空格函数的方法
Oct 21 Python
我喜欢你 抖音表白程序python版
Apr 07 Python
Python中输入和输出(打印)数据实例方法
Oct 13 Python
python中的RSA加密与解密实例解析
Nov 18 Python
python中Lambda表达式详解
Nov 20 Python
python之生成多层json结构的实现
Feb 27 Python
浅谈pycharm导入pandas包遇到的问题及解决
Jun 01 Python
keras load model时出现Missing Layer错误的解决方式
Jun 11 Python
安装python依赖包psycopg2来调用postgresql的操作
Jan 01 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 Error与Logging函数的深入理解
2013/06/03 PHP
php实现专业获取网站SEO信息类实例
2015/04/02 PHP
yii去掉必填项中星号的方法
2015/12/28 PHP
PHP的数组中提高元素查找与元素去重的效率的技巧解析
2016/03/03 PHP
PHP中explode函数和split函数的区别小结
2016/08/24 PHP
PHP 验证身份证是否合法的函数
2017/02/09 PHP
基于laravel belongsTo使用详解
2019/10/18 PHP
javascript 词法作用域和闭包分析说明
2010/08/12 Javascript
JS高级拖动技术 setCapture,releaseCapture
2011/07/31 Javascript
js和php如何获取当前url的内容
2013/09/22 Javascript
用JavaScript实现类似于ListBox功能示例代码
2014/03/09 Javascript
jquery重复提交请求的原因浅析
2014/05/23 Javascript
使用时间戳解决ie缓存的问题
2014/08/20 Javascript
一个不错的仿携程自定义数据下拉选择select
2014/09/01 Javascript
简单介绍JavaScript数据类型之隐式类型转换
2015/12/28 Javascript
js+css3实现旋转效果
2017/01/20 Javascript
利用Angular+Angular-Ui实现分页(代码加简单)
2017/03/10 Javascript
node.js中cluster的使用教程
2017/06/09 Javascript
5分钟打造简易高效的webpack常用配置
2017/07/04 Javascript
JavaScript中防止微信浏览器被整体拖动的方法
2017/08/25 Javascript
小程序点赞收藏功能的实现代码示例
2018/09/07 Javascript
node实现分片下载的示例代码
2018/10/17 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
layui 上传文件_批量导入数据UI的方法
2019/09/23 Javascript
跟老齐学Python之网站的结构
2014/10/24 Python
Python psutil模块简单使用实例
2015/04/28 Python
python通过定义一个类实例作为ftp回调方法
2015/05/04 Python
python获取一组数据里最大值max函数用法实例
2015/05/26 Python
Python实现代码统计工具(终极篇)
2016/07/04 Python
Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解
2019/02/28 Python
PyCharm2018 安装及破解方法实现步骤
2019/09/09 Python
python实现一个猜拳游戏
2020/04/05 Python
html5 touch事件实现触屏页面上下滑动(二)
2016/03/10 HTML / CSS
高中美术教学反思
2014/01/19 职场文书
领导走群众路线整改措施思想汇报
2014/10/12 职场文书
商务代表岗位职责
2015/02/15 职场文书