问题描述
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/FindNext
或 Items.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 线程很有帮助。