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中处理XML的教程
Apr 29 Python
Python数据结构之翻转链表
Feb 25 Python
Python 编码Basic Auth使用方法简单实例
May 25 Python
python3实现公众号每日定时发送日报和图片
Feb 24 Python
python3处理含有中文的url方法
May 10 Python
Python3.7中安装openCV库的方法
Jul 11 Python
python3利用Socket实现通信的方法示例
May 06 Python
python简单验证码识别的实现方法
May 10 Python
python中property和setter装饰器用法
Dec 19 Python
Tensorflow训练MNIST手写数字识别模型
Feb 13 Python
通过实例解析Python文件操作实现步骤
Sep 21 Python
Python制作一个随机抽奖小工具的实现
Jul 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 中的类
2006/10/09 PHP
PHP与MySQL交互使用详解
2006/10/09 PHP
php根据一个给定范围和步进生成数组的方法
2015/06/19 PHP
mac系统下为 php 添加 pcntl 扩展
2016/08/28 PHP
ThinkPHP框架整合微信支付之Native 扫码支付模式一图文详解
2019/04/09 PHP
PHP实现提高SESSION响应速度的几种方法详解
2019/08/09 PHP
PHP后门隐藏的一些技巧总结
2020/11/04 PHP
javascript面向对象之Javascript 继承
2010/05/04 Javascript
mysql输出数据赋给js变量报unterminated string literal错误原因
2010/05/22 Javascript
提升你网站水平的jQuery插件集合推荐
2011/04/19 Javascript
Yii2使用Bootbox插件实现自定义弹窗
2015/04/02 Javascript
js插件设置innerHTML时在IE8下提示“未知运行时错误”解决方法
2015/04/25 Javascript
jQuery实现别踩白块儿网页版小游戏
2017/01/18 Javascript
JQuery实现图片轮播效果
2017/05/08 jQuery
Nodejs实现用户注册功能
2019/04/14 NodeJs
JavaScript实现PC端四格密码输入框功能
2020/02/19 Javascript
[01:25:38]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第一场 1月19日
2021/03/11 DOTA
Python中捕捉详细异常信息的代码示例
2014/09/18 Python
使用Python中的cookielib模拟登录网站
2015/04/09 Python
python实现俄罗斯方块
2018/06/26 Python
python画折线图的程序
2018/07/26 Python
python自动发送测试报告邮件功能的实现
2019/01/22 Python
Python实现多进程的四种方式
2019/02/22 Python
tensorflow使用range_input_producer多线程读取数据实例
2020/01/20 Python
jupyter notebook读取/导出文件/图片实例
2020/04/16 Python
Python爬虫入门有哪些基础知识点
2020/06/02 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
基于Django快速集成Echarts代码示例
2020/12/01 Python
萨克斯第五大道精品百货店: Saks Fifth Avenue
2017/04/28 全球购物
信息技术专业个人自我评价
2013/12/11 职场文书
给小学生的新年寄语
2014/04/04 职场文书
财务人员担保书
2014/05/13 职场文书
小学生环保标语
2014/06/13 职场文书
婚礼女方父母答谢词
2015/01/04 职场文书
2016年班主任培训心得体会
2016/01/07 职场文书
运动会主持人开幕词
2016/03/04 职场文书