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闭包的两个注意事项(推荐)
Mar 20 Python
python+selenium实现京东自动登录及秒杀功能
Nov 18 Python
Python cookbook(数据结构与算法)找到最大或最小的N个元素实现方法示例
Feb 13 Python
详解Django中间件执行顺序
Jul 16 Python
pycham查看程序执行的时间方法
Nov 29 Python
DataFrame:通过SparkSql将scala类转为DataFrame的方法
Jan 29 Python
Python中numpy模块常见用法demo实例小结
Mar 16 Python
Python面向对象程序设计多继承和多态用法示例
Apr 08 Python
python 中如何获取列表的索引
Jul 02 Python
Python小程序 控制鼠标循环点击代码实例
Oct 08 Python
python中把元组转换为namedtuple方法
Dec 09 Python
python常量折叠基础知识点讲解
Feb 28 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
中东人咖啡哲学
2021/03/03 咖啡文化
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
2011/10/29 PHP
php去除换行(回车换行)的三种方法
2014/03/26 PHP
php检测数组长度函数sizeof与count用法
2014/11/17 PHP
php实现的用户查询类实例
2015/06/18 PHP
Yii安装与使用Excel扩展的方法
2016/07/13 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
2017/09/16 PHP
基于JQuery的浮动DIV显示提示信息并自动隐藏
2011/02/11 Javascript
jquery maxlength使用说明
2011/09/09 Javascript
前台js对象在后台转化java对象的问题探讨
2013/12/20 Javascript
jQuery异步获取json数据方法汇总
2014/12/22 Javascript
jquery实现滑屏大图定时收缩为小banner图片的广告代码
2015/09/02 Javascript
纯js代码制作的网页时钟特效【附实例】
2016/03/30 Javascript
AngularJs表单验证实例代码解析
2016/11/29 Javascript
Javascript之面向对象--接口
2016/12/02 Javascript
jQuery插件HighCharts绘制2D带有Legend的饼图效果示例【附demo源码下载】
2017/03/10 Javascript
JS验证码实现代码
2017/09/14 Javascript
利用原生JavaScript实现造日历轮子实例代码
2019/05/08 Javascript
layUI实现三级导航菜单效果
2019/07/26 Javascript
vue router 传参获取不到的解决方式
2019/11/13 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
2020/05/19 jQuery
Python 过滤字符串的技巧,map与itertools.imap
2008/09/06 Python
10种检测Python程序运行时间、CPU和内存占用的方法
2015/04/01 Python
运用TensorFlow进行简单实现线性回归、梯度下降示例
2018/03/05 Python
深入分析python数据挖掘 Json结构分析
2018/04/21 Python
django 解决扩展自带User表遇到的问题
2020/05/14 Python
Python爬取你好李焕英豆瓣短评生成词云的示例代码
2021/02/24 Python
css3实现背景颜色渐变让图片不再是唯一的实现方式
2012/12/18 HTML / CSS
Farfetch中文官网:奢侈品牌时尚购物平台
2020/03/15 全球购物
介绍一下linux的文件权限
2014/07/20 面试题
企业党员公开承诺书
2014/03/26 职场文书
《果园机器人》教学反思
2014/04/13 职场文书
舞蹈专业求职信
2014/06/13 职场文书
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js
图文详解nginx日志切割的实现
2022/01/18 Servers
tomcat的catalina.out日志按自定义时间格式进行分割的操作方法
2022/04/02 Servers