Outlook自動化

目錄

前言

Outlook是在Windows平台上很常見且功能強大的一個電子郵件軟體,藉由Python可以透過操作Outlook來自動收發電子郵件與其它功能來實現Outlook的自動化。

安裝win32com套件

$ pip3 install pypiwin32

$ pip3 install pywin32

補充:

pypiwin32pywin32實際上是相同的Python套件,只是因爲歷史因素,這個套件在不同的平台上有不同的稱呼。

在Windows平台上,通常稱為:pywin32,因爲它提供了操作Windows API的能力。而在PyPI上,這個套件稱為:pypiwin32,這個名稱可以更明確地反映出它是一個Python套件,可以在Windows上使用。

總之,無論使用哪一個名稱,這個套件都提供了許多可以操作Windows API的模組和函式,例如:操作註冊表、管理程序、操作COM物件等等。因此,如果在Windows平台上開發Python應用程式,這個套件可以在Windows上完成各種系統層級的工作。

引入套件

import win32com.client

注意:

使用pypiwin32套件操作Outlook時,Outlook必須是開啟的狀態才會動作。

基本操作

打開outlook

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")

取得所有email帳號

for account in outlook.Accounts:
    print(account, type(account.DeliveryStore.DisplayName))

accounts = win32com.client.Dispatch("Outlook.Application").Session.Accounts

for account in accounts:
    print(account, type(account.DeliveryStore.DisplayName))

直接指定要取得的帳號

accounts.Item(1)

注意:

帳號的編號是從1開始,而不是從0開始

取得總共有幾個email帳號

len(accounts)

取得信箱所有目錄

mailbox = outlook.Folders(accounts.Item(1).DeliveryStore.DisplayName)

for folder in mailbox.Folders:
    print(folder)

取得指定的信箱目錄

方法一:以信箱名稱來取得該信箱的目錄

folder = outlook.Folders('xxxxx@gmail.com').Folders('收件匣')

補充:

如果該目錄下還有子目錄,可以再透過Folders()方法來取得所有子目錄

方法二:以信箱編號來取得該信箱的目錄

folder = outlook.Folders(1).Folders('收件匣')

注意:

編號從1開始,1表示取得第1個email帳號

取得信箱的目錄數量

mailbox = outlook.Folders('xxxxx@gmail.com')
count = len(mailbox.Folders)

取得預設信箱

folder = outlook.getDefaultFolder(6)

代號說明:

说明
6 收件匣
4 寄件
5 寄件備份
3 垃圾桶

接收email

outlook.SendAndReceive(True)

說明:

参数False代表不把接收時的進度顯示出来,如果要顯示則改為True即可。

取得信箱內email

取得信目錄內所有email

messages = folders.Items

for message in messages:
    if hasattr(message, 'Sender'):
        print(message.Sender)
    print(message.SenderName)
    print(message.SenderEmailAddress)
    print(message.Subject)
    print(message.ReceivedTime)
    print(message.Body)
    if hasattr(message, 'HTMLBody'):
        print(message.HTMLBody)

注意:

因為有些屬性可能不存在,因此建議先用hasatter()函式檢查該屬性使否存在再行取值。

可以拿到的email屬性
屬性 說明
Sender 寄件人
SenderName 寄件人名字
SenderEmailAddress 寄件人email
To 收件人email
Subject email標題
Body email文字內容
HTMLBody email HTML內容
Attachments 附件

取得附件

attachments = message.attachments
print('附件數量:', attachments.Count)

for attachment in attachments:
    print(attachment.filename) # 附件的檔名
    attachment.SaveAsFile('D:\\data\\' + attachment.filename)

注意:

  1. 存檔的路徑必須是絕對路徑
  2. 如果檔案已經存在,會覆蓋掉原本的檔案。

取得email回覆狀態

reply_status = message.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x10810003")

說明:

0 = 未回覆

102 = 回覆給寄件人

103 = 全部回覆

email過濾

messages = folders.Items.Restrict('[Subject]="安全性快訊"').Restrict('[Body]="aaronbeango@gmail.com"')

可以過濾的條件與上面屬性相同

注意:

此過濾方式,其條件必須完全吻合,無法做部分條件過濾(例如搜尋標題內包含有「安全」兩個字的所有email),如果需要做部分條件過濾,則需要使用Outlook查詢語言DASL。

DASL過濾

只取得今天的email
Items.Restrict("@SQL=%today(urn:schemas:httpmail:datereceived)%")
取得指定日期的email
Items.Restrict("@SQL=(urn:schemas:httpmail:datereceived >= '2024-04-01 00:00')")
取得日期區間的email
Items.Restrict("@SQL=(urn:schemas:httpmail:datereceived >= '2024-04-01 00:00' AND urn:schemas:httpmail:datereceived <= '2024-04-01 23:59')")
以寄件人來過濾
Items.Restrict("@SQL=(urn:schemas:httpmail:sender like '%aaron%')")
過濾標題中有包含的文字
Items.Restrict("@SQL=(urn:schemas:httpmail:subject LIKE '%包含的文字%')")
過濾標題為Google的文字
Items.Restrict("@SQL=(urn:schemas:httpmail:subject = 'Google')")
以內容來搜尋
Items.Restrict("@SQL=(urn:schemas:httpmail:textdescription LIKE '%包含的文字%')")

將email存到硬碟

message.SaveAs(r'D:\emails\save.msg')

注意:

  1. 檔名必須是完整的絕對路徑,且副檔名為.msg
  2. 如果存檔的檔案已經存在,會存檔失敗。

回覆email

replyall_email = message.ReplyAll()
replyall_email.Body = "回覆的內容"
replyall_email.HTMLBody = "回覆HTML的內容"
replyall_email.Send()

**補充:

BodyHTMLBody擇一即可。

如果要直接回覆給寄件人,則呼叫:

message.Reply()

發送email

取得outlook元件

outlook = win32com.client.Dispatch("Outlook.Application")

建立新的email

mail = outlook.CreateItem(0)

指定要使用的email帳號

# 取得第一個email帳號
account= win32com.client.Dispatch("Outlook.Application").Session.Accounts.Item(1)
mail._oleobj_.Invoke(*(64209,0,8,0,account))

補充:

如果沒有指定email帳號,預設會使用第一個email帳號來發送email

指定收件人

mail.To = 'xxxxx@gmail.com'

指定多個收件人

mail.To = 'xxxxx01@gmail.com;xxxxx02@gmail.com;xxxxx03@gmail.com'

指定副本收件人

mail.CC = 'xxxxx@gmail.com'

指定多個副本收件人

mail.CC = 'xxxxx01@gmail.com;xxxxx02@gmail.com;xxxxx03@gmail.com'

指定密件收件人

mail.BCC = 'xxxxx@gmail.com'

指定多個密件收件人

mail.BCC = 'xxxxx01@gmail.com;xxxxx02@gmail.com;xxxxx03@gmail.com'

設定email標題

mail.Subject = '我是標題'

設定email內容

mail.Body = '我是內容'

設定email HTML格式內容

mail.HTMLBody = '<h1>我是HTML內容</h1>'

補充:

mail.Bodymail.HTMLBody同時設定時,只有mail.HTMLBody會生效。

設定附件

mail.Attachments.Add(r'D:\data\file.txt')

補充:

需要提供完整的檔案絕對路徑

以Outlook視窗顯示要發送的email內容

mail.Display(True)

發送email

mail.Send()