Python獲取微軟Microsoft Exchange郵件信息


目前我們公司使用的是微軟的exchange企業郵箱

最近有個臨時任務是寫個獲取郵件信息的模塊

百度了一下, 沒有發現目前還可以使用的代碼

下面貼出我寫的模塊, 親測可用

 

import datetime
from exchangelib import (
    Credentials,
    Account,
    DELEGATE,
    Configuration,
    FileAttachment,
    EWSDateTime,
    EWSTimeZone,
)
from exchangelib.protocol import CachingProtocol


class EmailLoader:
    def __init__(self, username, password):
        self.username = username
        self.password = password
        self.account = self.connect_to_mailbox()

    def connect_to_mailbox(self):
        cred = Credentials(self.username, self.password)
        config = Configuration(server="outlook.office365.com", credentials=cred,)
        account = Account(
            primary_smtp_address=self.username,
            config=config,
            autodiscover=False,
            access_type=DELEGATE,
        )
        print("--------Connected--------")
        return account

    def get_email_list(self, send_time_gte, subject_like=None, sender=None):
        """

        :param send_time_gte: must be specified
        :param subject_like: if None, it means no restrictions
        :param sender: if None, it means no restrictions
        :return: list type
        """
        tz = EWSTimeZone.timezone("Asia/Shanghai")
        email_list = []
        send_time_gte = datetime.datetime.strptime(send_time_gte, "%Y-%m-%d")
        inbox = self.account.inbox.filter(
            datetime_sent__gte=tz.localize(
                EWSDateTime(send_time_gte.year, send_time_gte.month, send_time_gte.day)
            )
        )

        for item in inbox.all().order_by("-datetime_sent"):
            subject = item.subject
            if not item.sender:
                continue
            sender_name = item.sender.name
            send_time = (item.datetime_sent + datetime.timedelta(hours=8)).strftime(
                "%Y-%m-%d %H:%M:%S"
            )
            b1 = (
                True
                if not subject_like or subject_like.lower() in subject.lower()
                else False
            )
            b2 = True if not sender or sender.lower() in sender_name.lower() else False

            if b1 and b2:
                email_list.append([subject, sender_name, send_time])
        print("get {} email(s) in total".format(len(email_list)))
        return email_list

    def download_email(self, subject, sender, send_time):
        """
        all three parameters must be specified
        only download one email each time
        :param subject:
        :param sender:
        :param send_time:
        :return: dict type
        """
        tz = EWSTimeZone.timezone("UTC")
        _dict = {}
        send_time = datetime.datetime.strptime(
            send_time, "%Y-%m-%d %H:%M:%S"
        ) - datetime.timedelta(hours=8)
        send_time = tz.localize(
            EWSDateTime(
                send_time.year,
                send_time.month,
                send_time.day,
                send_time.hour,
                send_time.minute,
                send_time.second,
            )
        )
        inbox = (
            self.account.inbox.filter(datetime_sent__gte=send_time,)
            .filter(datetime_sent__lte=send_time)
            .filter(subject__icontains=subject)
        )

        for item in inbox.all().order_by("-datetime_sent"):
            if sender.lower() in item.sender.name.lower():
                _dict["content"] = item.text_body
                _dict["attachments"] = [
                    {"name": attachment.name, "content": attachment.content}
                    for attachment in item.attachments
                    if isinstance(attachment, FileAttachment)
                ]
                if _dict:
                    print('one mail meets conditions')
                return _dict
            return

    @staticmethod
    def close_connections():
        CachingProtocol.clear_cache()


emailLoader = EmailLoader(username="***@***.com", password="***")
email_list = emailLoader.get_email_list(send_time_gte="2020-03-10")
print(email_list[0][2])  # latest mail sent-time
print(email_list[-1][2])  # oldest mail sent-time
latest_mail = emailLoader.download_email(
    email_list[0][0], email_list[0][1], email_list[0][2]
)
oldest_mail = emailLoader.download_email(
    email_list[-1][0], email_list[-1][1], email_list[-1][2]
)
emailLoader.close_connections()

需要注意的點有:

1.時區問題, 默認獲取到的郵件發送時間是UTC時間, 跟北京時間相差8個小時, 按照實際需求需要轉化一下

2.self.account.inbox.filter似乎不能傳入可以篩選郵件發送人名字sender.name的參數, 導致代碼復雜了一些

后續我的boss沒有提出什么修改意見了,  我也沒有過多使用和優化細節

Thanks !


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM