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中用pycurl监控http响应时间脚本分享
Feb 02 Python
Python正则获取、过滤或者替换HTML标签的方法
Jan 28 Python
Python实现对象转换为xml的方法示例
Jun 08 Python
python3安装pip3(install pip3 for python 3.x)
Apr 03 Python
使用PyCharm创建Django项目及基本配置详解
Oct 24 Python
Django渲染Markdown文章目录的方法示例
Jan 02 Python
python多线程并发让两个LED同时亮的方法
Feb 18 Python
python实现弹跳小球
May 13 Python
Python安装selenium包详细过程
Jul 23 Python
Python爬取知乎图片代码实现解析
Sep 17 Python
Python:type、object、class与内置类型实例
Dec 25 Python
python怎么提高计算速度
Jun 11 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 Mysql编程之高级技巧
2008/08/27 PHP
PHP中break及continue两个流程控制指令区别分析
2011/04/18 PHP
Yii2框架引用bootstrap中日期插件yii2-date-picker的方法
2016/01/09 PHP
Thinkphp实现短信验证注册功能
2016/10/18 PHP
解决jquery .ajax 在IE下卡死问题的解决方法
2009/10/26 Javascript
JavaScript中函数声明优先于变量声明的实例分析
2012/03/01 Javascript
JavaScript 中的日期和时间及表示标准介绍
2013/08/21 Javascript
AngularJS实现数据列表的增加、删除和上移下移等功能实例
2016/09/05 Javascript
基于Vue.js实现tab滑块效果
2017/07/23 Javascript
解决Layui选择全部,换页checkbox复选框重新勾选的问题方法
2018/08/14 Javascript
vue页面切换过渡transition效果
2018/10/08 Javascript
iview在vue-cli3如何按需加载的方法
2018/10/31 Javascript
Vue中util的工具函数实例详解
2019/07/08 Javascript
jquery css实现流程进度条
2020/03/26 jQuery
python中实现定制类的特殊方法总结
2014/09/28 Python
Python的math模块中的常用数学函数整理
2016/02/04 Python
python交互式图形编程实例(三)
2017/11/17 Python
pycharm下打开、执行并调试scrapy爬虫程序的方法
2017/11/29 Python
python 阶乘累加和的实例
2019/02/01 Python
nginx黑名单和django限速,最简单的防恶意请求方法分享
2019/08/09 Python
python利用dlib获取人脸的68个landmark
2019/11/27 Python
python实现批量处理将图片粘贴到另一张图片上并保存
2019/12/12 Python
Python运行DLL文件的方法
2020/01/17 Python
搭建pypi私有仓库实现过程详解
2020/11/25 Python
Python爬虫入门教程02之笔趣阁小说爬取
2021/01/24 Python
Foot Locker澳洲官网:美国运动服和鞋类零售商
2019/10/11 全球购物
彪马香港官方网上商店:PUMA香港
2020/12/06 全球购物
4s店机修工岗位职责
2013/12/20 职场文书
杠杆的科学教学反思
2014/01/10 职场文书
大四自我鉴定
2014/02/08 职场文书
工作说明书范文
2014/05/07 职场文书
2015年元旦文艺晚会总结(学院)
2014/11/28 职场文书
2015年招聘工作总结
2014/12/12 职场文书
服务明星事迹材料
2014/12/29 职场文书
《纸船和风筝》教学反思
2016/02/18 职场文书
中国古代史学名著《战国策》概述
2019/08/09 职场文书