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监控主机是否存活并以邮件报警
Sep 22 Python
Python网络爬虫项目:内容提取器的定义
Oct 25 Python
浅谈Python 的枚举 Enum
Jun 12 Python
Python列表list内建函数用法实例分析【insert、remove、index、pop等】
Jul 24 Python
使用11行Python代码盗取了室友的U盘内容
Oct 23 Python
python找出完数的方法
Nov 12 Python
浅谈Python_Openpyxl使用(最全总结)
Sep 05 Python
Python字符串中删除特定字符的方法
Jan 15 Python
使用python自动追踪你的快递(物流推送邮箱)
Mar 17 Python
python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码
Jan 06 Python
python glom模块的使用简介
Apr 13 Python
python通过函数名调用函数的几种方法总结
Jun 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
Apache下禁止php文件被直接访问的解决方案
2013/04/25 PHP
php中操作memcached缓存进行增删改查数据的实现代码
2014/08/15 PHP
PHP抓取淘宝商品的用户晒单评论+图片+搜索商品列表实例
2016/04/14 PHP
Array对象方法参考
2006/10/03 Javascript
jQuery 获取对象 基本选择与层级
2010/05/31 Javascript
jquery表单验证框架提供的身份证验证方法(示例代码)
2013/12/27 Javascript
JS的get和set使用示例
2014/02/20 Javascript
jQuery 顶部导航跟随滚动条滚动固定浮动在顶部
2014/06/06 Javascript
jquery+easeing实现仿flash的载入动画
2015/03/10 Javascript
window.onload绑定多个事件的两种解决方案
2016/05/15 Javascript
JS获取地址栏参数的两种方法(简单实用)
2016/06/14 Javascript
使用JavaScript判断手机浏览器是横屏还是竖屏问题
2016/08/02 Javascript
AngularJS过滤器filter用法实例分析
2016/11/04 Javascript
详解angularjs中如何实现控制器和指令之间交互
2017/05/31 Javascript
详解ES6语法之可迭代协议和迭代器协议
2018/01/13 Javascript
node 解析图片二维码的内容代码实例
2019/09/11 Javascript
用python代码做configure文件
2014/07/20 Python
Python中模块string.py详解
2017/03/12 Python
python enumerate函数的使用方法总结
2017/11/15 Python
Python列表list排列组合操作示例
2018/12/18 Python
Python中按值来获取指定的键
2019/03/04 Python
基于python实现ROC曲线绘制广场解析
2020/06/28 Python
Python 发送邮件方法总结
2020/08/10 Python
Django admin组件的使用
2020/10/24 Python
Python爬虫后获取重定向url的两种方法
2021/01/19 Python
加拿大女装网上购物:Reitmans
2016/10/20 全球购物
求职自荐信
2013/12/14 职场文书
大学运动会通讯稿
2014/01/28 职场文书
家长通知书教师评语
2014/04/17 职场文书
创先争优活动心得体会
2014/09/04 职场文书
党员应该树立反腐倡廉的坚定意识思想汇报
2014/09/12 职场文书
贪污受贿检讨书范文
2014/11/19 职场文书
2014年医院后勤工作总结
2014/12/06 职场文书
于丹论语心得观后感
2015/06/15 职场文书
导游词之安徽巢湖
2019/12/26 职场文书
javascript中Set、Map、WeakSet、WeakMap区别
2022/12/24 Javascript