2009-02-27 17 views
7

Moja aplikacja jest napisana w pythonie. Co robię, to uruchamiam skrypt na każdym e-mailu otrzymanym przez Postfix i robię coś z treścią e-mail. Procmail jest odpowiedzialny za uruchomienie skryptu, który przyjmuje e-mail jako dane wejściowe. Problem zaczął się, gdy konwertowałem komunikat wejściowy (może to być tekst) na obiekt email_message (ponieważ ten drugi przydaje się). Używam email.message_from_string (gdzie e-mail jest domyślnym modułem e-mail, jest dostarczany z pythonem).Treść wiadomości e-mail jest czasem łańcuchem i czasem listą. Czemu?

import email message = email.message_from_string(original_mail_content) message_body = message.get_payload()

Ten MESSAGE_BODY czasami powrocie listę [wystąpienie email.message.Message, przykład email.message.Message] i kiedyś powrocie ciąg (rzeczywista zawartość treści wiadomości przychodzących). Dlaczego tak jest. I nawet znalazłem jeszcze jedną obserwację. Przeglądając dokumentację e-mail.message.Message.get_payload(), znalazłem to ..
"" " Ładunek będzie obiektem listowym lub łańcuchem znaków.Jeśli zmutujesz obiekt obiekt listy, modyfikujesz ładunek komunikatu w miejscu ... "" ""

Jak mam ogólną metodę pobierania treści wiadomości e-mail przez pythona? Proszę pomóż mi.

Odpowiedz

11

Cóż, odpowiedzi są poprawne, należy przeczytać dokumenty, ale na przykład sposób ogólny:

def get_first_text_part(msg): 
    maintype = msg.get_content_maintype() 
    if maintype == 'multipart': 
     for part in msg.get_payload(): 
      if part.get_content_maintype() == 'text': 
       return part.get_payload() 
    elif maintype == 'text': 
     return msg.get_payload() 

ta jest podatna na jakiś katastrofy, jak można sobie wyobrazić, że części mogą sami mają multiparts , i to naprawdę zwraca tylko pierwszą część tekstu, więc może to być również błędne, ale możesz z nią grać.

+0

Na liście wiadomości, o której mówiłem, próbowałem uruchomić get_payload() na każdym z obiektów. Obie zwracają to samo. Czy jeden obiekt jest klonem drugiego, więc jeśli dostanę wywołanie get_payload na jednej części, zrobię to ??? –

+0

Zależy od tego, co zostało wysłane. Często można na przykład uzyskać tekst/html i wersję tekstową/prostą tego samego. Można zmodyfikować funkcję, aby wyszukać i preferować tekst/zwykły typ zawartości względem innych tekstów/typów. – bobince

+0

Niesamowite bobince.Masz absolutną rację: D –

10

Jak szalony, jak mogłoby się wydawać, powodem, dla którego czasami łańcucha, czasem list-semantyka są given in the documentation. Zasadniczo wiadomości wieloczęściowe są zwracane jako listy.

+0

że. Jest. Zwariowany. –

9

Zamiast po prostu patrząc na pod-strony, stosowanie odległości(), aby wykonać iterację treści wiadomości

def walkMsg(msg): 
    for part in msg.walk(): 
    if part.get_content_type() == "multipart/alternative": 
     continue 
    yield part.get_payload(decode=1) 

Spacer() zwraca iterator, że można pętla z (czyli jest to generator) . Jeśli komunikat nie jest kontenerem części (tzn. Nie ma załączników ani alternatyw), metoda walk() zwróci iterator z pojedynczym elementem - samą wiadomością.

Chcesz pominąć wszystkie części "wieloczęściowe", ponieważ są one po prostu klejem.

Powyższa metoda zwraca wszystkie czytelne części. Możesz to rozwinąć, aby po prostu zwrócić części tekstu, jeśli zawierają one informacje, których szukasz.

Należy zauważyć, że jak Pythona 2.5 Metody get_type() get_main_type() i get_subtype() zostały usunięte ->http://docs.python.org/library/email.message.html#email.message.Message.walk

+0

To jest znacznie lepsza odpowiedź niż ta, która została zaakceptowana przez OP, IMHO. –

+0

Myślę, że pojedyncze "=" powinno być "==" w instrukcji if – veered

+0

Dzięki - poprawione – timbo