2011-08-23 6 views
10

पर ध्यान दिए बिना इसे सादा पाठ में डीकोड करना मैं एक थंडरबर्ड एमबॉक्स फ़ाइल से ईमेल संदेशों के निकाय को निकालने के लिए पायथन 3 का उपयोग करने की कोशिश कर रहा हूं। यह एक आईएमएपी खाता है।एमबॉक्स फ़ाइल से ईमेल के निकाय को निकालने, चार्टसेट और कंटेंट ट्रांसफर एन्कोडिंग

मैं एक यूनिकोड स्ट्रिंग के रूप में प्रक्रिया के लिए उपलब्ध ईमेल के शरीर का टेक्स्ट हिस्सा रखना चाहता हूं। यह थंडरबर्ड में ईमेल जैसा दिखता है, और \ r \ n = 20 आदि जैसे बच निकले वर्णों को शामिल नहीं करना चाहिए

मुझे लगता है कि यह सामग्री स्थानांतरण एन्कोडिंग है जो मुझे नहीं पता कि कैसे डीकोड करना है या नहीं हटाना। मुझे विभिन्न सामग्री प्रकारों और विभिन्न सामग्री स्थानांतरण एन्कोडिंग के साथ ईमेल प्राप्त होते हैं। यह मेरे वर्तमान प्रयास है:

import mailbox 
import quopri,base64 

def myconvert(encoded,ContentTransferEncoding): 
    if ContentTransferEncoding == 'quoted-printable': 
     result = quopri.decodestring(encoded) 
    elif ContentTransferEncoding == 'base64': 
     result = base64.b64decode(encoded) 

mboxfile = 'C:/Users/Username/Documents/Thunderbird/Data/profile/ImapMail/server.name/INBOX' 

for msg in mailbox.mbox(mboxfile): 
    if msg.is_multipart(): #Walk through the parts of the email to find the text body. 
     for part in msg.walk(): 
      if part.is_multipart(): # If part is multipart, walk through the subparts. 
       for subpart in part.walk(): 
        if subpart.get_content_type() == 'text/plain': 
         body = subpart.get_payload() # Get the subpart payload (i.e the message body) 
        for k,v in subpart.items(): 
          if k == 'Content-Transfer-Encoding': 
           cte = v    # Keep the Content Transfer Encoding 
      elif subpart.get_content_type() == 'text/plain': 
       body = part.get_payload()   # part isn't multipart Get the payload 
       for k,v in part.items(): 
        if k == 'Content-Transfer-Encoding': 
         cte = v      # Keep the Content Transfer Encoding 

print(body) 
print('Body is of type:',type(body)) 
body = myconvert(body,cte) 
print(body) 

लेकिन इस के साथ विफल:

Body is of type: <class 'str'> 
Traceback (most recent call last): 
File "C:/Users/David/Documents/Python/test2.py", line 31, in <module> 
    body = myconvert(body,cte) 
File "C:/Users/David/Documents/Python/test2.py", line 6, in myconvert 
    result = quopri.decodestring(encoded) 
File "C:\Python32\lib\quopri.py", line 164, in decodestring 
    return a2b_qp(s, header=header) 
TypeError: 'str' does not support the buffer interface 
+0

कि अजीब बात है। get_payload() बाइट्स को वापस करना चाहिए, लेकिन पायथन 3 के नीचे str, जब तक कि आप 'decode = True' में पास न हों, जो आप नहीं करते हैं। –

+0

मैंने इसे डीकोड = ट्रू के साथ अभी कोशिश की है, और यह बाइट्स लौटाता है, और इसलिए कोई त्रुटि नहीं है। ऐसा लगता है कि डिकोडिंग किया जाता है, और अब मुझे बस बाइट्स को स्ट्रिंग में कनवर्ट करना है। हालांकि मैंने अभी भी परीक्षण एन्कोडिंग की विस्तृत विविधता वाले ईमेल के साथ परीक्षण नहीं किया है। – dcb

+0

हू, यह एक बग की तरह लगता है, यह चारों ओर एक और तरीका होना चाहिए, डीकोड = सही स्ट्र और डीकोड = झूठी बाइट्स लौटना चाहिए। :-) –

उत्तर

17

यहाँ कुछ कोड है कि काम करता है है, यह बजाय उन संदेशों को जहां यह विफल हो जाएगा के लिए दुर्घटनाग्रस्त की त्रुटियों प्रिंट करता है। मुझे उम्मीद है कि यह उपयोगी हो सकता है। ध्यान दें कि यदि पाइथन 3 में कोई बग है, और यह तय किया गया है, तो लाइनें .get_payload (decode = True) फिर बाइट ऑब्जेक्ट की बजाय एक स्ट्र ऑब्जेक्ट लौटा सकती है। मैंने आज 2.7.2 और पायथन 3.2.1 पर यह कोड चलाया।

import mailbox 

def getcharsets(msg): 
    charsets = set({}) 
    for c in msg.get_charsets(): 
     if c is not None: 
      charsets.update([c]) 
    return charsets 

def handleerror(errmsg, emailmsg,cs): 
    print() 
    print(errmsg) 
    print("This error occurred while decoding with ",cs," charset.") 
    print("These charsets were found in the one email.",getcharsets(emailmsg)) 
    print("This is the subject:",emailmsg['subject']) 
    print("This is the sender:",emailmsg['From']) 

def getbodyfromemail(msg): 
    body = None 
    #Walk through the parts of the email to find the text body.  
    if msg.is_multipart():  
     for part in msg.walk(): 

      # If part is multipart, walk through the subparts.    
      if part.is_multipart(): 

       for subpart in part.walk(): 
        if subpart.get_content_type() == 'text/plain': 
         # Get the subpart payload (i.e the message body) 
         body = subpart.get_payload(decode=True) 
         #charset = subpart.get_charset() 

      # Part isn't multipart so get the email body 
      elif part.get_content_type() == 'text/plain': 
       body = part.get_payload(decode=True) 
       #charset = part.get_charset() 

    # If this isn't a multi-part message then get the payload (i.e the message body) 
    elif msg.get_content_type() == 'text/plain': 
     body = msg.get_payload(decode=True) 

    # No checking done to match the charset with the correct part. 
    for charset in getcharsets(msg): 
     try: 
      body = body.decode(charset) 
     except UnicodeDecodeError: 
      handleerror("UnicodeDecodeError: encountered.",msg,charset) 
     except AttributeError: 
      handleerror("AttributeError: encountered" ,msg,charset) 
    return body  


#mboxfile = 'C:/Users/Username/Documents/Thunderbird/Data/profile/ImapMail/server.name/INBOX' 
print(mboxfile) 
for thisemail in mailbox.mbox(mboxfile): 
    body = getbodyfromemail(thisemail) 
    print(body[0:1000]) 
2

यह स्क्रिप्ट सभी संदेशों को सही ढंग से वापस जाने के लिए लगता है:

def getcharsets(msg): 
    charsets = set({}) 
    for c in msg.get_charsets(): 
     if c is not None: 
      charsets.update([c]) 
    return charsets 

def getBody(msg): 
    while msg.is_multipart(): 
     msg=msg.get_payload()[0] 
    t=msg.get_payload(decode=True) 
    for charset in getcharsets(msg): 
     t=t.decode(charset) 
    return t 

एसीडी से पूर्व जवाब अक्सर ही वास्तविक संदेश के कुछ पाद लेख देता है। ( कम से कम GMANE ईमेल messagens मैं इस टूलबॉक्स के लिए खोलने हूँ में: https://pypi.python.org/pypi/gmane )

चियर्स

संबंधित मुद्दे