[英]Read Emails From Outlook using Python Fails if Meeting Invites Are Present
通过从网络上的资源中学习和实验,我已经能够编写出一些代码。
每当我的 Outlook 邮箱中有会议邀请时,我都会陷入困境。 代码无法执行。
寻找有关如何在 Python 中处理异常的指南。
import csv
import win32com.client
from datetime import datetime
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
# Create empty list to store results
data_set = list()
date_id = (datetime.today()).strftime('%Y%m%d') # Used to create the filename
#Iterating through email items in outlook folder
for message in messages:
if messages is not None:
if len(inbox.Items) > 0:
row = list()
row.append(message.Subject)
row.append(message.Categories)
row.append(message.Sender)
#row.append(message.Sender.Address)
row.append(message.To)
row.append(message.SentOn)
row.append(message.CC)
row.append(message.BCC)
# Stores the data in a list
data_set.append(row)
# Print out the result to a csv with headers
with open(date_id + "_"+ 'outlook_Data.csv', 'w', newline='', encoding='utf-8') as csv_file:
headers = ['Subject', 'Category', 'From', 'To', 'Sent On', 'CC', 'BCC']
wr = csv.writer(csv_file, delimiter=',')
wr.writerow(headers)
for line in data_set:
wr.writerow(line)
这个问题归结为一个过滤问题:我们有一个不同类型的对象列表,其中一些不能被处理。
出于此答案的目的,让收件箱中的电子邮件对象的类型为Message
,会议邀请的类型为MeetingInvitation
。
可以应用这四种方法中的任何一种。
尝试/除外/继续
for message in messages: row = list() try: row.append(message.Subject) row.append(message.Categories) row.append(message.Sender) ... # Stores the data in a list data_set.append(row) except AttributeError as ex: print('Error', ex, 'skipping message', message) continue
检查循环顶部对象的类型
for message in messages: if isinstance(message, MeetingInvitation): continue row = list()
使用过滤器内置函数
filtered_messages = filter(lambda msg: not isinstance(msg, MeetingInvitation), messages) for message in filtered_messages: row = list() ...
使用列表理解(如果有很多消息,生成器理解会更有效 - 将[]
替换为()
)
filtered_messages = [msg for msg in msgs if not isinstance(msg, MeetingInvitation)] for message in filtered_messages: row = list() ...
可以撤销 isinstance 检查以排除任何不是Message
if not isinstance(message, Message):
continue
或扩展以排除其他有问题的类型
if isinstance(message, (MeetingInvitation, SomethingElse)):
continue
所有四种方法在功能上都是等效的。 在我看来,过滤器和列表理解方法更简洁,因为它们将过滤过程与实际的消息处理分开。
特别感谢@snakecharmerb 帮助克服挑战。 如果其他人可能需要处理类似的事情,则完整的工作代码如下。
import csv
import win32com.client
from datetime import datetime
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
# Create empty list to store results
data_set = list()
date_id = (datetime.today()).strftime('%Y%m%d') # Used to create the filename
#Iterating through email items in outlook folder
for message in messages:
row = list()
try:
row.append(message.Subject)
row.append(message.Categories)
row.append(message.Sender)
row.append(message.Sender.Address)
row.append(message.To)
row.append(message.SentOn)
row.append(message.CC)
row.append(message.BCC)
# Stores the data in a list
data_set.append(row)
except AttributeError as ex:
print('Error', ex, 'skipping message', message)
continue
# Print out the result to a csv with headers
with open(date_id + "_"+ 'outlook_Data.csv', 'w', newline='', encoding='utf-8') as csv_file:
headers = ['Subject', 'Category', 'From', 'To', 'Sent On', 'CC', 'BCC']
wr = csv.writer(csv_file, delimiter=',')
wr.writerow(headers)
for line in data_set:
wr.writerow(line)
如果您想跳过 OUTLOOK CALADER 项目,这是另一种解决方案,使用下面的item.MessageClass
是示例代码和参考链接以获取更多详细信息
https://docs.microsoft.com/en-us/office/vba/outlook/Concepts/Forms/item-types-and-message-classes
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
messages.Sort("[ReceivedTime]", True)
for i, msg in enumerate(messages):
print(msg.MessageClass) # use this in condition
if msg.MessageClass=='IPM.Note':
print('Its a Meeting')
# Identify outlook exchange user
if msg.SenderEmailType == "EX":
print(msg.Sender.GetExchangeUser().PrimarySmtpAddress)
msg_sender = msg.Sender.GetExchangeUser().PrimarySmtpAddress
else:
print(msg.SenderEmailAddress)
msg_sender = msg.SenderEmailAddress
elif msg.MessageClass =='IPM.Schedule.Meeting.Request':
print('Its a Meeting')
# Check only first 20 items change the number as required
if i > 20:
break
Some Outputs from above code IPM.Note IPM.Note IPM.Schedule.Meeting.Request Its a Meeting IPM.Note IPM.Schedule.Meeting.Request Its a Meeting
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.