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通过urllib2获取带有中文参数url内容的方法
Mar 13 Python
使用IPython下的Net-SNMP来管理类UNIX系统的教程
Apr 15 Python
Python使用xlrd模块操作Excel数据导入的方法
May 26 Python
python Crypto模块的安装与使用方法
Dec 21 Python
django实现用户注册实例讲解
Oct 30 Python
关于Python 常用获取元素 Driver 总结
Nov 24 Python
如何使用 Python 读取文件和照片的创建日期
Sep 05 Python
Pycharm配置lua编译环境过程图解
Nov 28 Python
Python 利用argparse模块实现脚本命令行参数解析
Dec 28 Python
python 实现IP子网计算
Feb 18 Python
Python语言规范之Pylint的详细用法
Jun 24 Python
Pandas 稀疏数据结构的实现
Jul 25 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使用pack处理二进制文件的方法
2014/07/03 PHP
JavaScript 定义function的三种方式小结
2009/10/16 Javascript
JQuery获取当前屏幕的高度宽度的实现代码
2011/07/12 Javascript
javascript实现促销倒计时+fixed固定在底部
2013/09/18 Javascript
JavaScript-RegExp对象只能使用一次问题解决方法
2014/06/23 Javascript
JQuery中使用.each()遍历元素学习笔记
2014/11/08 Javascript
深入分析javascript中console命令
2016/08/14 Javascript
Bootstrap CDN和本地化环境搭建
2016/10/26 Javascript
扩展jquery easyui tree的搜索树节点方法(推荐)
2016/10/28 Javascript
基于node.js制作简单爬虫教程
2017/06/29 Javascript
在 Vue 项目中引入 tinymce 富文本编辑器的完整代码
2018/05/04 Javascript
微信小程序与公众号实现数据互通的方法
2019/07/25 Javascript
element-ui中按需引入的实现
2019/12/25 Javascript
jquery插件懒加载的示例
2020/10/24 jQuery
vue使用element-ui实现表单验证
2020/12/13 Vue.js
[06:01]刀塔次级联赛top10第一期
2014/11/07 DOTA
[01:34]2016国际邀请赛中国区预选赛IG战队教练采访
2016/06/27 DOTA
[39:53]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第一场 11.19
2020/11/19 DOTA
在Python中使用异步Socket编程性能测试
2014/06/25 Python
利用python将图片转换成excel文档格式
2017/12/30 Python
把csv文件转化为数组及数组的切片方法
2018/07/04 Python
python生成器与迭代器详解
2019/01/01 Python
PyCharm 创建指定版本的 Django(超详图解教程)
2019/06/18 Python
python中def是做什么的
2020/06/10 Python
django表单中的按钮获取数据的实例分析
2020/07/31 Python
Python基于pyjnius库实现访问java类
2020/07/31 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
2020/11/10 Python
洛杉矶生活休闲而精致的基础品牌:Mika Jaymes
2018/01/07 全球购物
French Connection官网:女装、男装及家居用品
2019/03/18 全球购物
AssertionError 跟一下那个类是 “is – a”的关系
2012/02/21 面试题
教育专业自荐书范文
2013/12/17 职场文书
高中自我评价范文
2014/01/27 职场文书
食品厂厂长岗位职责
2014/01/30 职场文书
教师一岗双责责任书
2014/04/16 职场文书
2014领导班子专题民主生活会对照检查材料思想汇报
2014/09/23 职场文书
2015大学迎新标语
2015/07/16 职场文书