2011-02-22 28 views
31

Próbuję napisać krótki program, który będzie czytał zawartość e-maili w folderze na moim profilu wymiany/Outlooka, aby móc manipulować danymi. Jednak mam problem ze znalezieniem wielu informacji na temat integracji Pythona i Exchange/Outlook. Wiele rzeczy jest albo bardzo starych/nie ma dokumentów/nie wyjaśniono. Próbowałem już kilku fragmentów, ale wydaje się, że otrzymuję te same błędy. Próbowałem Tim złoty za kod:Czytanie e-maili z Outlooka za pomocą Pythona poprzez MAPI

import win32com.client 

session = win32com.client.gencache.EnsureDispatch ("MAPI.Session") 

# 
# Leave blank to be prompted for a session, or use 
# your own profile name if not "Outlook". It is also 
# possible to pull the default profile from the registry. 
# 
session.Logon ("Outlook") 
messages = session.Inbox.Messages 

# 
# Although the inbox_messages collection can be accessed 
# via getitem-style calls (inbox_messages[1] etc.) this 
# is the recommended approach from Microsoft since the 
# Inbox can mutate while you're iterating. 
# 
message = messages.GetFirst() 
while message: 
    print message.Subject 
    message = messages.GetNext() 

Jednakże pojawia się błąd:

pywintypes.com_error: (-2147221005, 'Invalid class string', None, None) 

Nie wiem, co moja nazwa profilu jest tak próbowałem z:

session.Logon() 

zostać poproszony ale to też nie działało (ten sam błąd). Próbowano również zarówno z Otwieraniem i zamykaniem Outlooka, jak i bez zmian.

+1

Czy rozważałeś korzystanie z protokołu IMAP na serwerze, a nie w zależności od klienta Outlook? W zależności od przypadku użycia protokół IMAP może okazać się wydajny i znacznie bardziej przenośny (zarówno klienci, jak i serwery). –

+1

@Jason IMAP wygląda dobrze, ale niestety nie jest włączony na używanym koncie. – johnharris85

Odpowiedz

42

Miałem ten sam problem co ty - nie znalazłeś wiele, co działało. Poniższy kod działa jednak jak urok.

import win32com.client 

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") 

inbox = outlook.GetDefaultFolder(6) # "6" refers to the index of a folder - in this case, 
            # the inbox. You can change that number to reference 
            # any other folder 
messages = inbox.Items 
message = messages.GetLast() 
body_content = message.body 
print body_content 
+2

Czy istnieje sposób, aby zobaczyć inne atrybuty wiadomości? Chciałbym użyć twojego przykładu, aby uzyskać datę i godzinę otrzymania wiadomości. – sequoia

+4

znalazłem rozwiązanie: 'message.CreationTime' z jakiegoś powodu atrybuty nie pojawiają się, kiedy używam dir() – sequoia

+5

@ sequoia - Używanie listy właściwości COM dla MailItems (np. Wiadomości Outlook) to sposób, w jaki znalazłem wszystkie właściwości wiadomości (na przykład message.SenderEmailAddress): http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.mailitem_properties.aspx – wardw123

8

Stworzyłem własny iterator do iterowania obiektów Outlook za pośrednictwem Pythona. Problem polega na tym, że pyton próbuje iterować zaczynając od Index [0], ale program Outlook oczekuje pierwszego elementu Index [1] ... Aby uczynić go bardziej prostym w Ruby, poniżej jest klasa pomocnicza Oli z następującymi metodami:

.items() - otrzymuje krotkę (indeks elementu) ...

.prop() - pomaga introspekcji perspektywy przedmiotu poddawanie dostępne właściwości (metody i atrybuty)

from win32com.client import constants 
from win32com.client.gencache import EnsureDispatch as Dispatch 

outlook = Dispatch("Outlook.Application") 
mapi = outlook.GetNamespace("MAPI") 

class Oli(): 
    def __init__(self, outlook_object): 
     self._obj = outlook_object 

    def items(self): 
     array_size = self._obj.Count 
     for item_index in xrange(1,array_size+1): 
      yield (item_index, self._obj[item_index]) 

    def prop(self): 
     return sorted(self._obj._prop_map_get_.keys()) 

for inx, folder in Oli(mapi.Folders).items(): 
    # iterate all Outlook folders (top level) 
    print "-"*70 
    print folder.Name 

    for inx,subfolder in Oli(folder.Folders).items(): 
     print "(%i)" % inx, subfolder.Name,"=> ", subfolder 
0

miałem ten sam problem. Łącząc różne podejścia z internetu (i powyżej) pochodzić z następującym podejściu (checkEmails.py)

class CheckMailer: 

     def __init__(self, filename="LOG1.txt", mailbox="Mailbox - Another User Mailbox", folderindex=3): 
      self.f = FileWriter(filename) 
      self.outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI").Folders(mailbox) 
      self.inbox = self.outlook.Folders(folderindex) 


     def check(self):     
     #=============================================================================== 
     # for i in xrange(1,100):       #Uncomment this section if index 3 does not work for you 
     #  try: 
     #   self.inbox = self.outlook.Folders(i)  # "6" refers to the index of inbox for Default User Mailbox 
     #   print "%i %s" % (i,self.inbox)   # "3" refers to the index of inbox for Another user's mailbox 
     #  except: 
     #   print "%i does not work"%i 
     #=============================================================================== 

       self.f.pl(time.strftime("%H:%M:%S")) 
       tot = 0     
       messages = self.inbox.Items 
       message = messages.GetFirst() 
       while message: 
        self.f.pl (message.Subject) 
        message = messages.GetNext() 
        tot += 1 
       self.f.pl("Total Messages found: %i" % tot) 
       self.f.pl("-" * 80) 
       self.f.flush() 

if __name__ == "__main__": 
    mail = CheckMailer() 
    for i in xrange(320): # this is 10.6 hours approximately 
      mail.check() 
      time.sleep(120.00) 

Dla concistency I obejmują również kod dla klasy FileWriter (znaleziono w FileWrapper.py). Potrzebowałem tego, ponieważ próbuje potokować UTF8 do pliku w systemie Windows nie działa.

class FileWriter(object): 
    ''' 
    convenient file wrapper for writing to files 
    ''' 


    def __init__(self, filename): 
     ''' 
     Constructor 
     ''' 
     self.file = open(filename, "w") 

    def pl(self, a_string): 
     str_uni = a_string.encode('utf-8') 
     self.file.write(str_uni) 
     self.file.write("\n") 

    def flush(self): 
     self.file.flush()  

Ciesz się.

1

Przepraszamy za mój zły angielski. Sprawdzanie maili przy użyciu Pythona z MAPI jest łatwiej

outlook =win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") 
folder = outlook.Folders[5] 
Subfldr = folder.Folders[5] 
messages_REACH = Subfldr.Items 
message = messages_REACH.GetFirst() 

Tutaj możemy uzyskać najbardziej pierwszej wiadomości w skrzynce poczty lub w dowolnym folderze sub. W rzeczywistości musimy sprawdzić orientację skrzynki pocztowej pod numerem &. Za pomocą tej analizy możemy sprawdzić każdą skrzynkę pocztową & w jej folderach podkatalogów.

Podobnie znajdź poniższy kod, gdzie widzimy, ostatnie/wcześniejsze wiadomości. Jak musimy sprawdzić.

`outlook =win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") 
folder = outlook.Folders[5] 
Subfldr = folder.Folders[5] 
messages_REACH = Subfldr.Items 
message = messages_REACH.GetLast()` 

Dzięki temu możemy pobrać najnowszą wiadomość e-mail do skrzynki pocztowej. Zgodnie z wyżej wspomnianym kodem, możemy sprawdzić wszystkie nasze skrzynki pocztowe, & jej podkatalogi.