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开发中range()函数用法实例分析
Nov 12 Python
Python实现针对给定单链表删除指定节点的方法
Apr 12 Python
朴素贝叶斯分类算法原理与Python实现与使用方法案例
Jun 26 Python
Python后台管理员管理前台会员信息的讲解
Jan 28 Python
Django页面数据的缓存与使用的具体方法
Apr 23 Python
Django接收自定义http header过程详解
Aug 23 Python
Atom Python 配置Python3 解释器的方法
Aug 28 Python
Python高级编程之消息队列(Queue)与进程池(Pool)实例详解
Nov 01 Python
基于python实现把json数据转换成Excel表格
May 07 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
Jul 02 Python
解决python 虚拟环境删除包无法加载的问题
Jul 13 Python
python_tkinter弹出对话框创建
Mar 20 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入门基础之php代码写法
2011/12/30 PHP
str_replace只替换一次字符串的方法
2013/04/09 PHP
Symfony2函数用法实例分析
2016/03/18 PHP
音乐播放用的的几个函数
2006/09/07 Javascript
让JavaScript拥有类似Lambda表达式编程能力的方法
2010/09/12 Javascript
重载toString实现JS HashMap分析
2011/03/13 Javascript
formValidator3.3的ajaxValidator一些异常分析
2011/07/12 Javascript
js通过googleAIP翻译PHP系统的语言配置的实现代码
2011/10/17 Javascript
Jquery阻止事件冒泡 event.stopPropagation
2011/12/11 Javascript
JQuery的自定义事件代码,触发,绑定简单实例
2013/08/01 Javascript
在JavaScript中重写jQuery对象的方法实例教程
2014/08/25 Javascript
jQuery实现的简单提示信息插件
2015/12/08 Javascript
jQuery实现查找链接文字替换属性的方法
2016/06/27 Javascript
一个简单不报错的summernote 图片上传案例
2016/07/11 Javascript
AngularJS中实现动画效果的方法
2016/07/28 Javascript
js实现适合新闻类图片的轮播效果
2017/02/05 Javascript
jquery.flot.js简单绘制折线图用法示例
2017/03/13 Javascript
jQuery遮罩层实例讲解
2017/05/11 jQuery
requirejs按需加载angularjs文件实例
2017/06/08 Javascript
Vue2.x中利用@font-size引入字体图标报错的解决方法
2018/09/28 Javascript
mpvue+vuex搭建小程序详细教程(完整步骤)
2018/09/30 Javascript
Vue 事件处理操作实例详解
2019/03/05 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
2019/09/16 Javascript
Python利用带权重随机数解决抽奖和游戏爆装备问题
2016/06/16 Python
python代码实现ID3决策树算法
2017/12/20 Python
Python enumerate索引迭代代码解析
2018/01/19 Python
利用Python写一个爬妹子的爬虫
2018/06/08 Python
Python调用C++,通过Pybind11制作Python接口
2018/10/16 Python
pandas把所有大于0的数设置为1的方法
2019/01/26 Python
Python使用itchat模块实现简单的微信控制电脑功能示例
2019/08/26 Python
新加坡航空官方网站:Singapore Airlines
2016/10/13 全球购物
Hotels.com加拿大:领先的在线住宿网站
2018/10/05 全球购物
求职个人评价范文
2014/04/09 职场文书
老乡会致辞
2015/07/28 职场文书
2016优秀班主任个人先进事迹材料
2016/02/26 职场文书
SQL Server 忘记密码以及重新添加新账号
2022/04/26 SQL Server