Outlook是在Windows平台上很常見且功能強大的一個電子郵件軟體,藉由Python可以透過操作Outlook來自動收發電子郵件與其它功能來實現Outlook的自動化。
$ pip3 install pypiwin32
或
$ pip3 install pywin32
補充:
pypiwin32
和pywin32
實際上是相同的Python套件,只是因爲歷史因素,這個套件在不同的平台上有不同的稱呼。在Windows平台上,通常稱為:
pywin32
,因爲它提供了操作Windows API的能力。而在PyPI上,這個套件稱為:pypiwin32
,這個名稱可以更明確地反映出它是一個Python套件,可以在Windows上使用。總之,無論使用哪一個名稱,這個套件都提供了許多可以操作Windows API的模組和函式,例如:操作註冊表、管理程序、操作COM物件等等。因此,如果在Windows平台上開發Python應用程式,這個套件可以在Windows上完成各種系統層級的工作。
import win32com.client
注意:
使用pypiwin32套件操作Outlook時,Outlook必須是開啟的狀態才會動作。
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
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開始
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 | 垃圾桶 |
outlook.SendAndReceive(True)
說明:
参数False代表不把接收時的進度顯示出来,如果要顯示則改為True即可。
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()
函式檢查該屬性使否存在再行取值。
屬性 | 說明 |
---|---|
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)
注意:
- 存檔的路徑必須是絕對路徑
- 如果檔案已經存在,會覆蓋掉原本的檔案。
reply_status = message.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x10810003")
說明:
0 = 未回覆
102 = 回覆給寄件人
103 = 全部回覆
messages = folders.Items.Restrict('[Subject]="安全性快訊"').Restrict('[Body]="aaronbeango@gmail.com"')
可以過濾的條件與上面屬性相同
注意:
此過濾方式,其條件必須完全吻合,無法做部分條件過濾(例如搜尋標題內包含有「安全」兩個字的所有email),如果需要做部分條件過濾,則需要使用Outlook查詢語言DASL。
Items.Restrict("@SQL=%today(urn:schemas:httpmail:datereceived)%")
Items.Restrict("@SQL=(urn:schemas:httpmail:datereceived >= '2024-04-01 00:00')")
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 '%包含的文字%')")
Items.Restrict("@SQL=(urn:schemas:httpmail:subject = 'Google')")
Items.Restrict("@SQL=(urn:schemas:httpmail:textdescription LIKE '%包含的文字%')")
message.SaveAs(r'D:\emails\save.msg')
注意:
- 檔名必須是完整的絕對路徑,且副檔名為
.msg
- 如果存檔的檔案已經存在,會存檔失敗。
replyall_email = message.ReplyAll()
replyall_email.Body = "回覆的內容"
replyall_email.HTMLBody = "回覆HTML的內容"
replyall_email.Send()
**補充:
Body
和HTMLBody
擇一即可。
如果要直接回覆給寄件人,則呼叫:
message.Reply()
outlook = win32com.client.Dispatch("Outlook.Application")
mail = outlook.CreateItem(0)
# 取得第一個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'
mail.Subject = '我是標題'
mail.Body = '我是內容'
mail.HTMLBody = '<h1>我是HTML內容</h1>'
補充:
mail.Body
和mail.HTMLBody
同時設定時,只有mail.HTMLBody
會生效。
mail.Attachments.Add(r'D:\data\file.txt')
補充:
需要提供完整的檔案絕對路徑
mail.Display(True)
mail.Send()