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中字符串的常见操作技巧总结
Jul 28 Python
python爬虫实例详解
Jun 19 Python
对python多线程与global变量详解
Nov 09 Python
python+flask实现API的方法
Nov 21 Python
python 定时器,实现每天凌晨3点执行的方法
Feb 20 Python
python安装pil库方法及代码
Jun 25 Python
python字符串的拼接方法总结
Nov 18 Python
tensorboard 可以显示graph,却不能显示scalar的解决方式
Feb 15 Python
利用jupyter网页版本进行python函数查询方式
Apr 14 Python
Python CSS选择器爬取京东网商品信息过程解析
Jun 01 Python
详解Pycharm第三方库的安装及使用方法
Dec 29 Python
Python语言内置数据类型
Feb 24 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 获取远程文件内容的函数代码
2010/03/24 PHP
Laravel 5框架学习之向视图传送数据(进阶篇)
2015/04/08 PHP
weiphp微信公众平台授权设置
2016/01/04 PHP
浅谈php调用python文件
2019/03/29 PHP
jQuery 使用手册(一)
2009/09/23 Javascript
用JS判别浏览器种类以及IE版本的几种方法小结
2011/08/02 Javascript
Jquery AJAX POST与GET之间的区别
2013/11/14 Javascript
node中socket.io的事件使用详解
2014/12/15 Javascript
JS运动框架之分享侧边栏动画实例
2015/03/03 Javascript
jquery uploadify如何取消已上传成功文件
2017/02/08 Javascript
JS中如何实现Laravel的route函数详解
2017/02/12 Javascript
element-ui 限制日期选择的方法(datepicker)
2018/05/16 Javascript
微信小程序canvas实现刮刮乐效果
2018/07/09 Javascript
利用Blob进行文件上传的完整步骤
2018/08/02 Javascript
jquery分页插件pagination使用教程
2018/10/23 jQuery
Vue this.$router.push(参数)实现页面跳转操作
2020/09/09 Javascript
[01:07:41]IG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
简单谈谈python中的Queue与多进程
2016/08/25 Python
Python 实现 贪吃蛇大作战 代码分享
2016/09/07 Python
Mac 上切换Python多版本
2017/06/17 Python
python中使用正则表达式的后向搜索肯定模式(推荐)
2017/11/11 Python
Python3之不使用第三方变量,实现交换两个变量的值
2019/06/26 Python
详解Python并发编程之从性能角度来初探并发编程
2019/08/23 Python
Python模块的制作方法实例分析
2019/12/21 Python
Python函数式编程实例详解
2020/01/17 Python
基于Python数据分析之pandas统计分析
2020/03/03 Python
解决django 向mysql中写入中文字符出错的问题
2020/05/18 Python
Python Django中间件使用原理及流程分析
2020/06/13 Python
美国演唱会订票网站:Ticketmaster美国
2017/10/05 全球购物
Ralph Lauren法国官网:美国高品味时装品牌
2017/12/08 全球购物
Feelunique中文官网:欧洲最大化妆品零售电商
2020/07/10 全球购物
医学毕业生自荐信
2013/10/11 职场文书
党风廉政承诺书
2014/03/27 职场文书
热爱祖国的演讲稿
2014/05/04 职场文书
小学教师读书笔记
2015/07/01 职场文书
还在手动盖楼抽奖?教你用Python实现自动评论盖楼抽奖(一)
2021/06/07 Python