Read Emails From Outlook using Python Fails if Meeting Invites Are Present

梦想的初衷 提交于 2021-01-29 07:16:01

问题


I've been able to work out some code through some learning and experiments from resources on the web.

I'm stuck at a point that everytime an there is a meeting invite in my outlook mailbox. The code fails to execute.

Looking for guidance on how to handle the exception in 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)

回答1:


This problem reduces to a filtering problem: we have a list of objects of different types, some of which must not be processed.

For the purposes of this answer, let the email objects in the inbox be of type Message, and the meeting invitations be of type MeetingInvitation.

Any of these four approaches can be applied.

  1. try/except/continue

    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. Check the type of the object at the top of the loop

     for message in messages:
         if isinstance(message, MeetingInvitation):
             continue
         row = list()
    
  3. Use the filter built-in function

     filtered_messages = filter(lambda msg: not isinstance(msg, MeetingInvitation), messages)
     for message in filtered_messages:
         row = list()
         ...
    
  4. Use a list comprehension (If there are a lot of messages, a generator comprehension would be more efficient - replace [] with ())

     filtered_messages = [msg for msg in msgs if not isinstance(msg, MeetingInvitation)] 
     for message in filtered_messages:
         row = list()
         ...
    

The isinstance checks could be reversed to exclude anything that isn't a Message

if not isinstance(message, Message):
   continue

or extended to exclude other problematic types

if isinstance(message, (MeetingInvitation, SomethingElse)):
    continue

All of the four approaches are functionally equivalent. The filter and list comprehension approaches are cleaner, in my opinion, because they separate the filtering process from the actual message processing.




回答2:


Special thanks to @snakecharmerb for helping through the challenges. The complete working code is below if anyone else might need to work on something similar.

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)


来源:https://stackoverflow.com/questions/63721937/read-emails-from-outlook-using-python-fails-if-meeting-invites-are-present

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!