繁体   English   中英

如果存在会议邀请,则使用 Python 从 Outlook 读取电子邮件失败

[英]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

可以应用这四种方法中的任何一种。

  1. 尝试/除外/继续

    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
  2. 检查循环顶部对象的类型

     for message in messages: if isinstance(message, MeetingInvitation): continue row = list()
  3. 使用过滤器内置函数

     filtered_messages = filter(lambda msg: not isinstance(msg, MeetingInvitation), messages) for message in filtered_messages: row = list() ...
  4. 使用列表理解(如果有很多消息,生成器理解会更有效 - 将[]替换为()

     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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM