【问题标题】:Extract outlook email body and recipient email address using python使用 python 提取 Outlook 电子邮件正文和收件人电子邮件地址
【发布时间】:2019-01-09 02:25:45
【问题描述】:

我正在尝试提取 Outlook 电子邮件正文、收件人地址、主题和接收日期。

我能够提取主题和接收日期,但无法提取正文和收件人地址:

以下是我的主题代码和接收日期:

outlook = win32com.client.Dispatch('Outlook.Application').GetNamespace('MAPI')

namespace = outlook.Session

recipient = namespace.CreateRecipient("abc@xyz.com")

inbox = outlook.GetSharedDefaultFolder(recipient, 6)

messages = inbox.Items

email_subject = []

email_date = []

email_date_time = []


for x in messages:
    sub = x.Subject
    received_date = x.senton.date()
    received_date_time = str(x.ReceivedTime)
    email_subject.append(sub)
    email_date.append(received_date)
    email_date_time.append(received_date_time)

对于我正在尝试的身体:

for x in messages:
    body = x.Body
    print(body)

但这不起作用,我收到以下错误:

Traceback (most recent call last):

  File "<ipython-input-85-d79967933b99>", line 2, in <module>
    sub = x.Body

  File "C:\ProgramData\Anaconda3\lib\site-packages\win32com\client\dynamic.py", line 516, in __getattr__
    ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1)

com_error: (-2147467259, 'Unspecified error', None, None)

【问题讨论】:

  • “这不起作用”是什么意思?请包含错误的完整堆栈跟踪,或者如果没有错误,您需要描述实际输出可能与您期望的不同。
  • 我收到此错误:回溯(最近一次调用最后一次):文件“”,第 2 行,在 sub = x.Body 文件“C :\ProgramData\Anaconda3\lib\site-packages\win32com\client\dynamic.py",第 516 行,在 getattr 中 ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1 ) com_error: (-2147467259, '未指定的错误', 无, 无)
  • 另外,不应该是received_date = x.SentOn吗?我很确定senton.date() 在 Outlook 对象模型中无效。 Python 对于初学者来说是区分大小写的,并且没有date 属性或SentOn 属性的方法。
  • 此外,您在评论中提供的回溯与您提供的代码的任何部分都一致。请修改您的问题,使其连贯。
  • received_date = x.senton.date()....这对我来说非常好用。我也更新了问题。

标签: python email outlook win32com


【解决方案1】:

我刚刚在我的计算机上运行了类似的代码,在一个包含 3,000 多个混合类型的项目(Skype 消息通知、日历邀请/通知、电子邮件等)的收件箱中,我无法复制此错误,即使对于以下项目not m.Body -- 我认为这是一个可能的罪魁祸首,也许某种类型的项目没有主体会引发错误 -- 但情况似乎并非如此:

>>> for m in messages:
...     if not m.body:
...         print(m.Subject)
...         print(m.Body)
...
Accepted: Tables discussion

Message Recall Failure: tables/ new data status

Message Recall Failure: A few issues with the data

您可能应该添加print(m.Class),因为我仍然认为某些类型的项目可能没有Body 属性。

This thread 建议可能存在阻止以编程方式访问 Outlook 的用户/安全设置,因此您可能需要仔细检查(尽管我认为如果不允许,您的任何代码都不会工作 - 仍然,值得一看!)。

我已经找到了这个错误的来源。我们遇到了 comObjectModelGaurd 的问题。我们的组策略最近更改为禁止以编程方式访问受保护的 mailItem 对象。

修改 Outlook 用户信任设置或注册表将解决问题。

由于我无法复制错误,也许我仍然可以帮助您调试并确定问题的根源,从中我们可能会想出一个好的解决方案。

使用函数获取项目的主体,并使用try/except 识别哪些项目导致错误。

def getBody(m):
     s = ""
     try:
         s = m.Body
     except COMError:
         s = '\t'.join(('Error!', m.Class, m.senton.date(), m.Subject))
     return s


for m in messages:
    print(getBody(m))

【讨论】:

  • 非常感谢您的帮助。根据您的建议,我尝试了以下代码:def getBody(m): s = "" try: s = m.Body except COMError: s = '\t'.join(('Error!', m.Class, m.senton.date(), m.Subject)) return s for m in messages: print(getBody(m)) 然后我得到了这个错误---->>Traceback (most recent call last): File "&lt;ipython-input-84-473cc9cfd962&gt;", line 11, in &lt;module&gt; print(getBody(m)) File "&lt;ipython-input-84-473cc9cfd962&gt;", line 5, in getBody except COMError: NameError: name 'COMError' is not defined
  • 你可以把它改成 Error 而不是 COMError
  • 在尝试此代码def getBody(m): s = "" try: s = m.Body except Error: s = '\t'.join(('Error!', m.Class, m.senton.date(), m.Subject)) return s for m in messages: print(getBody(m)) 后,我仍然收到错误---->> Traceback (most recent call last): File "&lt;ipython-input-98-2c19cb4ddfd4&gt;", line 11, in &lt;module&gt; print(getBody(m)) File "&lt;ipython-input-98-2c19cb4ddfd4&gt;", line 5, in getBody except Error: NameError: name 'Error' is not defined
  • @biker007 好的,将其切换回Exception 而不是Error。你明白什么是 NameError 吗?您应该研究一下,还应该研究一下 python 中的基本错误处理:)
【解决方案2】:

我认为我找到了一个有效的解决方案。对我来说,这是权限问题,但我在 https://www.slipstick.com/developer/change-programmatic-access-options/ 中进行了注册表编辑,效果很好。

编辑:我认为这是通过取消阻止一些较低级别的权限来实现的,这些权限使外部程序能够访问 Outlook 客户端。

【讨论】:

  • 感谢分享,罗里。请在您的答案中解释解决方案以及为什么它对您有用,而不是仅仅发布链接,因为它们迟早会死。
【解决方案3】:

召回的电子邮件没有正文,因此我们可以通过 MessageClass 找到它并排除该特定类

for i in messages:
    if email.MessageClass != "IPM.Outlook.Recall":

【讨论】:

    猜你喜欢
    • 2011-08-24
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多