首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyWin32在从PST读取的所有电子邮件上排除一个特定的标签实例

PyWin32在从PST读取的所有电子邮件上排除一个特定的标签实例
EN

Stack Overflow用户
提问于 2021-02-13 02:22:25
回答 1查看 57关注 0票数 0

我一直在开发一个Python工具来摄取和写入所有来自PST的电子邮件,从Outlook导出到单独的.html文件。问题是,在outlook中打开PST并逐个检查电子邮件的源信息时,它包含以下特定行:

<meta http-equiv=Content-Type content="text/html; charset=utf-8">

当使用Pywin32导入PST并读取PST中的所有电子邮件时,不会包含该PST。去看看它是什么样子的-

来自Outlook:<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)">

从该工具导出的内容:<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta name=Generator content="Microsoft Word 15 (filtered medium)">

除了这一个标签之外,电子邮件的内容在其他方面完全相同。

我的代码:

代码语言:javascript
复制
htmlEmails = 0
encryptedEmails = 0
totalEmails = 0
richPlainEmails = 0
filenameCount = 1
mycounter2 = 1

#Adjusting name of PST location to be readable
selectedPST = str(selectedPST.replace('/', '\\'))
print('\nRunning:' , selectedPST)
outlook.AddStore(selectedPST)
PSTFolderObj = find_pst_folder(outlook, selectedPST)

def find_pst_folder(OutlookObj, pst_filepath):
    for Store in OutlookObj.Stores:
        if Store.IsDataFileStore  and Store.FilePath == pst_filepath:
            return Store.GetRootFolder()
    return None

def enumerate_folders(FolderObj):
    for ChildFolder in FolderObj.Folders:
        enumerate_folders(ChildFolder)
    iterate_messages(FolderObj)

def iterate_messages(FolderObj):
    global mycounter2
    global encryptedEmails
    global richPlainEmails
    global totalEmails
    global htmlEmails

    for item in FolderObj.Items:
        totalEmails += 1
        try:
            try:
                body_content = item.HTMLbody
                mysubject = item.Subject
                writeToFile(body_content, exportPath, mysubject)
                mycounter2 = mycounter2 + 1
                htmlEmails += 1
            except AttributeError:
                #print('Non HTML formatted email, passing')
                richPlainEmails += 1
                pass
        except Exception as e:
            encryptedEmails += 1
            pass

def writeToFile(messageHTML, path, mysubject):
    global mycounter2
    filename = '\htmloutput' + str(mycounter2) + '.html'

    #Check if email is rich or plain text first (only HTML emails are desired)
    if '<!-- Converted from text/plain format -->' in messageHTML or '<!-- Converted from text/rtf format -->' in messageHTML:
        raise AttributeError()

    else:
        file = open(path + filename, "x", encoding='utf-8')
        try:
            messageHTML = regex.sub('\r\n', '\n', messageHTML)
            file.write(messageHTML)
            
        #Handle any potential unexpected Unicode error
        except Exception as e:
            print('Exception: ' , e)
            try:
                #Prints email subject to more easily find the offending email
                print('Subject: ', mysubject)
                print(mycounter2)
                file.write(messageHTML)
            except Exception as e:
                print('Tried utf decode: ', e)
  
        file.close()

因为电子邮件在其他方面是相同的,所以我只能假设这是由库完成的。我想知道是不是元标签被排除了,或者是PyWin32中的一个bug?

EN

回答 1

Stack Overflow用户

发布于 2021-02-24 03:33:33

在与熟悉PyWin32的人进行了大量的探索和讨论,并对我的代码进行了审查和测试后,似乎Outlook在这里扮演了不好的角色。

我发现Outlook在将一封电子邮件附加到另一封电子邮件时会导致完全相同的行为。也就是说,如果我发送了一封电子邮件,我可以检查源信息,它包含了信息。然后,当我将其附加到另一封电子邮件时,该文件的标签将被剥离。

因此,我转而使用LibPFF ( https://pypi.org/project/libpff-python/ )来规避这个问题。它允许PST被读取,以及通过PST中电子邮件的HTML进行解析。

LibPFF的代码如下所示:(只需在path+pstname spot中包含PST的路径):

代码语言:javascript
复制
import pypff
pst_file = pypff.file()
pst_file.open(path+pstname)

root = pst_file.get_root_folder()

for folder in root.sub_folders:
    for sub in folder.sub_folders:
        for message in sub.sub_messages:
            body_content =  message.get_html_body()
            print(str(body_content))

这基本上是一种变通方法,但根据用例的不同,可以提供相同的结果。至于为什么Outlook会这样做,我只能假设带有字符集信息的标签是通过他们的服务器发送电子邮件所必需的,所以当它附加到另一封电子邮件时,它被视为无用并被剥离。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66177101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档