# Outlook自動化 ## 目錄 - [前言](#前言) - [基本操作](#基本操作) - [取得信箱內email](#取得信箱內email) - [發送email](#發送email) ## 前言 Outlook是在Windows平台上很常見且功能強大的一個電子郵件軟體,藉由Python可以透過操作Outlook來自動收發電子郵件與其它功能來實現Outlook的自動化。 #### 安裝win32com套件 ```bash $ pip3 install pypiwin32 ``` 或 ```bash $ pip3 install pywin32 ``` > **補充:** > > `pypiwin32`和`pywin32`實際上是相同的Python套件,只是因爲歷史因素,這個套件在不同的平台上有不同的稱呼。 > > 在Windows平台上,通常稱為:`pywin32`,因爲它提供了操作Windows API的能力。而在PyPI上,這個套件稱為:`pypiwin32`,這個名稱可以更明確地反映出它是一個Python套件,可以在Windows上使用。 > > 總之,無論使用哪一個名稱,這個套件都提供了許多可以操作Windows API的模組和函式,例如:操作註冊表、管理程序、操作COM物件等等。因此,如果在Windows平台上開發Python應用程式,這個套件可以在Windows上完成各種系統層級的工作。 #### 引入套件 ```python 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) ``` #### 取得信箱所有目錄 ```python mailbox = outlook.Folders(accounts.Item(1).DeliveryStore.DisplayName) for folder in mailbox.Folders: print(folder) ``` #### 取得指定的信箱目錄 方法一:以信箱名稱來取得該信箱的目錄 ```python 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 | 附件 | #### 取得附件 ```python 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過濾 ```python 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 ```less 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() ``` > **補充: > > `Body`和`HTMLBody`擇一即可。 如果要直接回覆給寄件人,則呼叫: ``` message.Reply() ``` ## 發送email #### 取得outlook元件 ```python outlook = win32com.client.Dispatch("Outlook.Application") ``` #### 建立新的email ``` mail = outlook.CreateItem(0) ``` #### 指定要使用的email帳號 ```python # 取得第一個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.Body`和`mail.HTMLBody`同時設定時,只有`mail.HTMLBody`會生效。 #### 設定附件 ``` mail.Attachments.Add(r'D:\data\file.txt') ``` > **補充:** > > 需要提供完整的檔案絕對路徑 #### 以Outlook視窗顯示要發送的email內容 ``` mail.Display(True) ``` #### 發送email ``` mail.Send() ```