Python 中的 Outlook 附件条件

问题描述

Python 的新手。我的目标是仅将 .xls 和 .docx 文件类型的某些发件人的电子邮件附件下载到指定的文件夹。我有发件人条件工作,但无法让程序过滤到我想要的特定文件类型。下面的代码从列出的发件人处下载所有附件,包括图像签名(不需要)。下载的附件包含将在 df 中进一步使用的数据。我想将它保留在 win32com 中,因为我有其他使用它的工作电子邮件抓取程序。我很感激任何建议。

部分工作代码

import win32com.client

Outlook = win32com.client.dispatch("outlook.application").GetNamespace("MAPI")
inBox = outlook.GetDefaultFolder(6)

Items = inBox.Items
Item = Items.GetFirst()

def saveAttachments(email:object):
        for attachedFile in email.Attachments:
                try:
                        filename = attachedFile.FileName
                        attachedFile.SaveAsFile("C:\\Outputfolder"+filename)
                except Exception as e:
                        print(e)
for mailItem in inBox.Items:
        if mailItem.SenderName  == "John Smith" or mailItem.SenderName  == "Mike Miller":
                saveAttachments(mailItem)

解决方法

首先,不要遍历文件夹中的所有项目 - 使用 Items.Find/FindNextItems.Restrict 查询 SenderName 属性 - 参见 https://docs.microsoft.com/en-us/office/vba/api/outlook.items.restrict

至于附件,图像附件与任何其他附件没有任何区别。您可以检查文件扩展名或大小。您还可以使用 PR_ATTACH_CONTENT_ID 读取 http://schemas.microsoft.com/mapi/proptag/0x3712001F 属性(DASL 名称 Attachment.PropertyAccessor.GetProperty)并检查它是否在 MailItem.HTMLBody 属性的 img 标记中使用。

,

当前您将所有附加文件保存在磁盘上:

 for attachedFile in email.Attachments:
                try:
                        filename = attachedFile.FileName
                        attachedFile.SaveAsFile("C:\\Outputfolder"+filename)
                except Exception as e:
                        print(e)

仅将 .xls 和 .docx 文件类型的某些发件人的电子邮件附件发送到指定文件夹。

Attachment.FileName 属性返回一个表示附件文件名的字符串。因此,通过提取文件扩展名来解析文件名将帮助您过滤应保存在磁盘上的文件。

您也可能有兴趣避免在邮件正文中使用用于内嵌图像的隐藏附件。这是 VBA 中的示例代码(Outlook 对象模型对于所有编程语言都是通用的,我对 Python 不熟悉)计算可见附件:

Sub ShowVisibleAttachmentCount()
    Const PR_ATTACH_CONTENT_ID As String = "http://schemas.microsoft.com/mapi/proptag/0x3712001F"
    Const PR_ATTACHMENT_HIDDEN As String = "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B"

    Dim m As MailItem
    Dim a As Attachment
    Dim pa As PropertyAccessor
    Dim c As Integer
    Dim cid as String

    Dim body As String

    c = 0

    Set m = Application.ActiveInspector.CurrentItem
    body = m.HTMLBody

    For Each a In m.Attachments
        Set pa = a.PropertyAccessor
        cid = pa.GetProperty(PR_ATTACH_CONTENT_ID)

        If Len(cid) > 0 Then
            If InStr(body,cid) Then
            Else
                'In case that PR_ATTACHMENT_HIDDEN does not exists,'an error will occur. We simply ignore this error and
                'treat it as false.
                On Error Resume Next
                If Not pa.GetProperty(PR_ATTACHMENT_HIDDEN) Then
                    c = c + 1
                End If
                On Error GoTo 0
            End If
        Else
            c = c + 1
        End If
    Next a
    MsgBox c
End Sub

您还可以检查邮件正文(请参阅 Outlook 项目的 HTMLBody 属性)是否包含 PR_ATTACH_CONTENT_ID 属性值。否则,如果未明确设置 PR_ATTACHMENT_HIDDEN 属性,则附加内容对用户可见。

您可能还会发现 Sending Outlook Email with embedded image using VBS 线程很有帮助。