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

2024-04-25 23:48:12 发布

您现在位置:Python中文网/ 问答频道 /正文

通过从网上的资源中学习和实验,我已经能够写出一些代码

每次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)

Tags: csvthetoinimportmessagedatadatetime
3条回答

特别感谢@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项,可以使用^{,下面是一个示例代码和参考链接,以获取更多详细信息

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

这个问题归结为一个过滤问题:我们有一个不同类型的对象列表,其中一些对象不能被处理

出于此回答的目的,让收件箱中的电子邮件对象的类型为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. 使用filter内置函数

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

     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

这四种方法在功能上都是等效的。在我看来,过滤和列表理解方法更干净,因为它们将过滤过程与实际的消息处理分开

相关问题 更多 >