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的高级Git库 Gittle
Sep 22 Python
用Python写一个无界面的2048小游戏
May 24 Python
python操作oracle的完整教程分享
Jan 30 Python
python 快速把超大txt文件转存为csv的实例
Oct 26 Python
django使用LDAP验证的方法示例
Dec 10 Python
Django web框架使用url path name详解
Apr 29 Python
Python使用matplotlib 画矩形的三种方式分析
Oct 31 Python
Pytorch提取模型特征向量保存至csv的例子
Jan 03 Python
python GUI库图形界面开发之PyQt5布局控件QVBoxLayout详细使用方法与实例
Mar 06 Python
浅谈numpy中np.array()与np.asarray的区别以及.tolist
Jun 03 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
Dec 14 Python
Jupyter Notebook添加代码自动补全功能的实现
Jan 07 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代码DOS造成用光网络带宽
2011/03/01 PHP
php实现的获取网站备案信息查询代码(360)
2013/09/23 PHP
PHP实现获取FLV文件的时间
2015/02/10 PHP
WordPress中对访客评论功能的一些优化方法
2015/11/24 PHP
CI框架无限级分类+递归的实现代码
2016/11/01 PHP
JS中简单的实现像C#中using功能(有源码下载)
2007/01/09 Javascript
ExtJS下书写动态生成的xml(兼容火狐)
2013/04/02 Javascript
两个select多选模式的选项相互移动(示例代码)
2014/01/11 Javascript
JS实现div居中示例
2014/04/17 Javascript
javascript父、子页面交互技巧总结
2014/08/08 Javascript
JavaScript简单实现鼠标移动切换图片的方法
2016/02/23 Javascript
Javascript技术栈中的四种依赖注入小结
2016/02/27 Javascript
BootStrap Tooltip插件源码解析
2016/12/27 Javascript
解决使用vue.js路由后失效的问题
2018/03/17 Javascript
layui表格分页 记录勾选的实例
2019/09/02 Javascript
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
Python开发编码规范
2006/09/08 Python
python判断字符串编码的简单实现方法(使用chardet)
2016/07/01 Python
Python K最近邻从原理到实现的方法
2019/08/15 Python
python中open函数的基本用法示例
2019/09/07 Python
django 文件上传功能的相关实例代码(简单易懂)
2020/01/22 Python
PyQt5的QWebEngineView使用示例
2020/10/20 Python
Django集成MongoDB实现过程解析
2020/12/01 Python
爱普生美国官网:Epson美国
2018/11/05 全球购物
泰国王权免税店官方网站:KingPower
2019/03/11 全球购物
法国高保真音响和家庭影院商店:Son Video
2019/04/26 全球购物
中学生在校期间的自我评价分享
2013/11/13 职场文书
干部选拔任用方案
2014/05/26 职场文书
2014年客房部工作总结
2014/11/22 职场文书
学校端午节活动总结
2015/02/11 职场文书
住房公积金贷款工资证明
2015/06/12 职场文书
劳保用品管理制度范本
2015/08/06 职场文书
大学军训口号大全
2015/12/24 职场文书
高一作文之暖冬
2019/11/09 职场文书
详解CSS不定宽溢出文本适配滚动
2021/05/24 HTML / CSS
Oracle 11g数据库使用expdp每周进行数据备份并上传到备份服务器
2022/06/28 Oracle