如何检查一段时间内进来的所有电子邮件?

时间:2017-07-31 21:03:30

标签: python email outlook pywin32

我有以下方法get_email(),基本上每20秒,获取最新的电子邮件,并在其上执行一系列其他方法。

def get_email():
    import win32com.client
    import os
    import time
    import datetime as dt

    date_time = time.strftime('%m-%d-%Y')

    outlook = win32com.client.Dispatch("Outlook.Application").GetNameSpace("MAPI")
    inbox = outlook.GetDefaultFolder(6)

    messages = inbox.Items
    message = messages.GetFirst()  # any time calling GetFirst(), you can get GetNext()....
    email_subject = message.subject
    email_sender = message.SenderEmailAddress
    attachments = message.Attachments
    body_content = message.body

    print ('From: ' + email_sender)
    print ('Subject: ' + email_subject)

    if attachments.Count > 0:
        print (str(attachments.Count) + ' attachments found.')
        for i in range(attachments.Count):
                email_attachment = attachments.Item(i+1)
                report_name = date_time + '_' + email_attachment.FileName
                print('Pushing attachment - ' + report_name + ' - to check_correct_email() function.')

                if check_correct_email(email_attachment, email_subject, report_name) == True:
                    save_incoming_report(email_attachment, report_name, get_report_directory(email_subject))
                else:
                    print('Not the attachment we are looking for.')
                    # add error logging here
                    break

    else: #***********add error logging here**************
        print('No attachment found.')

我的主要问题是:

  • 有没有办法可以每小时使用GetNext()函数迭代每封电子邮件,而不是每20秒获取一次最新邮件(这绝对不如搜索所有电子邮件那么高效)?

鉴于有两个功能:GetFirst()GetNext()我如何正确地保存最新的检查,然后检查所有尚未检查的功能?

您是否认为在Outlook中可能更容易设置不同的文件夹,我可以将所有这些报告推送到,然后按时间迭代它们?这里唯一的问题是,如果传入的报告是自动生成的,并且电子邮件之间的时间间隔小于20秒,甚至是1秒。

任何帮助都表示赞赏!

4 个答案:

答案 0 :(得分:7)

您可以使用Restrict function将邮件变量限制为过去一小时内发送的电子邮件,并对其中的每一封邮件进行迭代。限制从您的收件箱中获取完整的项目列表,并为您提供符合特定条件的列表,例如在指定时间范围内收到的项目。 (上面链接的MSDN文档列出了您可以限制的其他一些可能的属性。)

如果您每小时运行一次,您可以将收件箱限制为过去一小时内收到的邮件(可能是那些仍然需要搜索的邮件),并对这些邮件进行迭代。

以下是限制过去一小时(或一小时)内收到的电子邮件的示例:

import win32com.client
import os
import time
import datetime as dt

# this is set to the current time
date_time = dt.datetime.now()
# this is set to one hour ago
lastHourDateTime = dt.datetime.now() - dt.timedelta(hours = 1)
#This is set to one minute ago; you can change timedelta's argument to whatever you want it to be
lastMinuteDateTime = dt.datetime.now() - dt.timedelta(minutes = 1)

outlook = win32com.client.Dispatch("Outlook.Application").GetNameSpace("MAPI")
inbox = outlook.GetDefaultFolder(6)

# retrieve all emails in the inbox, then sort them from most recently received to oldest (False will give you the reverse). Not strictly necessary, but good to know if order matters for your search
messages = inbox.Items
messages.Sort("[ReceivedTime]", True)

# restrict to messages from the past hour based on ReceivedTime using the dates defined above.
# lastHourMessages will contain only emails with a ReceivedTime later than an hour ago
# The way the datetime is formatted DOES matter; You can't add seconds here.
lastHourMessages = messages.Restrict("[ReceivedTime] >= '" +lastHourDateTime.strftime('%m/%d/%Y %H:%M %p')+"'")

lastMinuteMessages = messages.Restrict("[ReceivedTime] >= '" +lastMinuteDateTime.strftime('%m/%d/%Y %H:%M %p')+"'")

print "Current time: "+date_time.strftime('%m/%d/%Y %H:%M %p')
print "Messages from the past hour:"

for message in lastHourMessages:
    print message.subject
    print message.ReceivedTime

print "Messages from the past minute:"

for message in lastMinuteMessages:
    print message.subject
    print message.ReceivedTime

# GetFirst/GetNext will also work, since the restricted message list is just a shortened version of your full inbox.
print "Using GetFirst/GetNext"
message = lastHourMessages.GetFirst()
while message:
    print message.subject
    print message.ReceivedTime
    message = lastHourMessages.GetNext()

你似乎每20秒运行一次,所以你可能会以不同的间隔运行它。如果您无法定期可靠地运行它(然后在timedelta中指定,例如hours = 1),您可以保存最近检查的电子邮件的ReceivedTime,并使用它来限制搜索。 (在这种情况下,保存的ReceivedTime将替换lastHourDateTime,而Restrict将检索在最后一次检查后发送的每封电子邮件。)

我希望这有帮助!

答案 1 :(得分:1)

我有一个类似的问题,并通过上述解决方案进行了研究。包括另一个通用示例,以防其他人发现它更容易:

import win32com.client
import os
import datetime as dt

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

# setup range for outlook to search emails (so we don't go through the entire inbox)
lastWeekDateTime = dt.datetime.now() - dt.timedelta(days = 7)
lastWeekDateTime = lastWeekDateTime.strftime('%m/%d/%Y %H:%M %p')  #<-- This format compatible with "Restrict"

# Select main Inbox
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items

# Only search emails in the last week:
messages = messages.Restrict("[ReceivedTime] >= '" + lastWeekDateTime +"'")

print(message.subject)
# Rest of code...

答案 2 :(得分:0)

使用导入日期时间,这是我想到的:

count = 0    
msg = messages[len(messages) - count - 1]
while msg.SentOn.strftime("%d-%m-%y") == datetime.datetime.today().strftime("%d-%m-%y"):
        msg = messages[len(messages) - count - 1]
        count += 1
        # Rest of the code

答案 3 :(得分:0)

以下解决方案提供了Outlook中过去30分钟内未读的文件夹邮件以及过去30分钟内的邮件计数

import win32com.client
import os
import time
import datetime as dt
# this is set to the current time
date_time = dt.datetime.now()

#This is set to one minute ago; you can change timedelta's argument to whatever you want it to be
last30MinuteDateTime = dt.datetime.now() - dt.timedelta(minutes = 30 )

outlook = win32com.client.Dispatch("Outlook.Application").GetNameSpace("MAPI")
inbox = outlook.GetDefaultFolder(6)

# retrieve all emails in the inbox, then sort them from most recently received to oldest (False will give you the reverse). Not strictly necessary, but good to know if order matters for your search
messages = inbox.Items.Restrict("[Unread]=true")
messages.Sort("[ReceivedTime]", True)




last30MinuteMessages = messages.Restrict("[ReceivedTime] >= '" +last30MinuteDateTime.strftime('%m/%d/%Y %H:%M %p')+"'")

print "Current time: "+date_time.strftime('%m/%d/%Y %H:%M %p')

print "Messages from the past 30 minute:"
c=0
for message in last30MinuteMessages:
    print message.subject
    print message.ReceivedTime
    c=c+1;

print "The count of meesgaes unread from past 30 minutes ==",c