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 相关文章推荐
Flask SQLAlchemy一对一,一对多的使用方法实践
Feb 10 Python
神经网络理论基础及Python实现详解
Dec 15 Python
python+selenium打印当前页面的titl和url方法
Jun 22 Python
在PyCharm下打包*.py程序成.exe的方法
Nov 29 Python
详解python中的线程与线程池
May 10 Python
python写入数据到csv或xlsx文件的3种方法
Aug 23 Python
tensorflow使用range_input_producer多线程读取数据实例
Jan 20 Python
python matplotlib模块基本图形绘制方法小结【直线,曲线,直方图,饼图等】
Apr 26 Python
Django权限设置及验证方式
May 13 Python
python实现文法左递归的消除方法
May 22 Python
一篇文章教你用python画动态爱心表白
Nov 22 Python
python使用PySimpleGUI设置进度条及控件使用
Jun 10 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
PHP5中MVC结构学习
2006/10/09 PHP
php中通过curl smtp发送邮件
2012/06/05 PHP
php猴子选大王问题解决方法
2015/05/12 PHP
PHP实现的分解质因数操作示例
2018/08/01 PHP
prototype 1.5相关知识及他人笔记
2006/12/16 Javascript
JavaScript 页面编码与浏览器类型判断代码
2010/06/03 Javascript
jquery 插件学习(四)
2012/08/06 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
2013/11/29 Javascript
加随机数引入脚本不让浏览器读取缓存
2014/09/04 Javascript
JavaScript的History API使搜索引擎抓取AJAX内容
2015/12/07 Javascript
jsonp跨域请求数据实现手机号码查询实例分析
2015/12/12 Javascript
前端程序员必须知道的高性能Javascript知识
2016/08/24 Javascript
jQuery图片加载失败替换默认图片方法汇总
2017/11/29 jQuery
vue axios 二次封装的示例代码
2017/12/08 Javascript
Vue使用Proxy监听所有接口状态的方法实现
2019/06/07 Javascript
如何用webpack4.0撸单页/多页脚手架 (jquery, react, vue, typescript)
2019/06/18 jQuery
JS实现点击发送验证码 xx秒后重新发送功能
2019/07/30 Javascript
Python中矩阵库Numpy基本操作详解
2017/11/21 Python
Python闭包之返回函数的函数用法示例
2018/01/27 Python
pyqt5让图片自适应QLabel大小上以及移除已显示的图片方法
2019/06/21 Python
python使用多线程+socket实现端口扫描
2020/05/28 Python
Python预测2020高考分数和录取情况
2020/07/08 Python
C++和python实现阿姆斯特朗数字查找实例代码
2020/12/07 Python
python如何修改文件时间属性
2021/02/05 Python
css3实现蒙版弹幕功能
2019/06/18 HTML / CSS
购买200个世界上最好的内衣品牌:Bare Necessities
2017/02/11 全球购物
怎样有效的进行自我评价
2013/10/06 职场文书
打架检讨书300字
2014/02/02 职场文书
物理教学随笔感言
2014/02/22 职场文书
教师应聘自荐信范文
2014/03/14 职场文书
2014年社区居委会主任重阳节讲话稿
2014/09/25 职场文书
初中家长评语大全
2014/12/26 职场文书
2015年学校教育教学工作总结
2015/04/22 职场文书
2016婚礼主持词开场白
2015/11/24 职场文书
街道办残联2016年助残日活动总结
2016/04/01 职场文书
祝福语集锦:送给毕业同学祝福语
2019/11/21 职场文书