为了账号安全,请及时绑定邮箱和手机立即绑定

使用python从邮件中下载附件

使用python从邮件中下载附件

慕田峪7331174 2022-10-18 16:59:00
我有多封包含附件的电子邮件。我想下载带有特定主题行的未读电子邮件附件。例如,我收到一封主题为“EXAMPLE”并包含附件的电子邮件。那么它会如何下面的代码,我试过但它不工作”这是一个 Python 代码#Subject line can be "EXAMPLE"       for subject_line in lst_subject_line:                 # typ, msgs = conn.search(None,'(UNSEEN SUBJECT "' + subject_line + '")')             typ, msgs = conn.search(None,'("UNSEEN")')             msgs = msgs[0].split()             print(msgs)             outputdir = "C:/Private/Python/Python/Source/Mail Reader"             for email_id in msgs:                    download_attachments_in_email(conn, email_id, outputdir)
查看完整描述

4 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

我能找到的大多数答案都已过时。

这是一个用于从 Gmail 帐户下载附件的 python (>=3.6) 脚本。

确保检查底部的过滤器选项并在您的谷歌帐户上启用不太安全的应用程序。


import os

from imbox import Imbox # pip install imbox

import traceback


# enable less secure apps on your google account

# https://myaccount.google.com/lesssecureapps


host = "imap.gmail.com"

username = "username"

password = 'password'

download_folder = "/path/to/download/folder"


if not os.path.isdir(download_folder):

    os.makedirs(download_folder, exist_ok=True)

    

mail = Imbox(host, username=username, password=password, ssl=True, ssl_context=None, starttls=False)

messages = mail.messages() # defaults to inbox


for (uid, message) in messages:

    mail.mark_seen(uid) # optional, mark message as read


    for idx, attachment in enumerate(message.attachments):

        try:

            att_fn = attachment.get('filename')

            download_path = f"{download_folder}/{att_fn}"

            print(download_path)

            with open(download_path, "wb") as fp:

                fp.write(attachment.get('content').read())

        except:

            print(traceback.print_exc())


mail.logout()



"""

Available Message filters: 


# Gets all messages from the inbox

messages = mail.messages()


# Unread messages

messages = mail.messages(unread=True)


# Flagged messages

messages = mail.messages(flagged=True)


# Un-flagged messages

messages = mail.messages(unflagged=True)


# Messages sent FROM

messages = mail.messages(sent_from='sender@example.org')


# Messages sent TO

messages = mail.messages(sent_to='receiver@example.org')


# Messages received before specific date

messages = mail.messages(date__lt=datetime.date(2018, 7, 31))


# Messages received after specific date

messages = mail.messages(date__gt=datetime.date(2018, 7, 30))


# Messages received on a specific date

messages = mail.messages(date__on=datetime.date(2018, 7, 30))


# Messages whose subjects contain a string

messages = mail.messages(subject='Christmas')


# Messages from a specific folder

messages = mail.messages(folder='Social')

"""

对于自签名证书,请使用:


...

import ssl

    

context = ssl._create_unverified_context()

mail = Imbox(host, username=username, password=password, ssl=True, ssl_context=context, starttls=False)

...

笔记:


不太安全的应用和您的 Google 帐户


为帮助确保您的帐户安全,自 2022 年 5 月 30 日起,Google 不再支持使用第三方应用或设备,这些应用或设备要求您仅使用您的用户名和密码登录您的 Google 帐户。


重要提示:此截止日期不适用于 Google Workspace 或 Google Cloud Identity 客户。这些客户的执行日期将在稍后的 Workspace 博客上公布。


SRC


2022 年 8 月 22 日更新:您应该能够创建一个应用程序密码来解决“不太安全的应用程序”功能消失的问题。(后者仍然可以在我的企业帐户中使用,但必须为我的消费者帐户创建一个应用程序密码。)使用 imaplib,我可以使用应用程序密码登录。


查看完整回答
反对 回复 2022-10-18
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

我发现这对我来说最有效。只需在运行程序时保持您的前景打开,它就会提取具有特定主题行的未读邮件。


import datetime

import os

import win32com.client



path = os.path.expanduser("~/Documents/xyz/folder_to_be_saved")  #location o file today = datetime.date.today()  # current date if you want current


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

inbox = outlook.GetDefaultFolder(6) 

messages = inbox.Items



def saveattachemnts(subject):

    for message in messages:

        if message.Subject == subject and message.Unread:

        #if message.Unread:  #I usually use this because the subject line contains time and it varies over time. So I just use unread


            # body_content = message.body

            attachments = message.Attachments

            attachment = attachments.Item(1)

            for attachment in message.Attachments:

                attachment.SaveAsFile(os.path.join(path, str(attachment)))

                if message.Subject == subject and message.Unread:

                    message.Unread = False

                break                

                

saveattachemnts('EXAMPLE 1')

saveattachemnts('EXAMPLE 2')


查看完整回答
反对 回复 2022-10-18
?
长风秋雁

TA贡献1757条经验 获得超7个赞

from imap_tools import MailBox


# get all attachments from INBOX and save them to files

with MailBox('imap.my.ru').login('acc', 'pwd', 'INBOX') as mailbox:

    for msg in mailbox.fetch():

        for att in msg.attachments:

            print(att.filename, att.content_type)

            with open('C:/1/{}'.format(att.filename), 'wb') as f:

                f.write(att.payload)

https://github.com/ikvk/imap_tools


查看完整回答
反对 回复 2022-10-18
?
临摹微笑

TA贡献1982条经验 获得超2个赞

我使用该解决方案从邮箱获取附件。由您决定,下载或保存到本地变量。另外请注意,我首先阅读了所有消息,因为大多数时候盒子都是空的:


import imaplib

import email



class MailBox:

    SMTP_SERVER = 'imap.gmail.com'

    SMTP_PORT = 993

    USER = '<user_email>'

    PASSWORD = '<password>'


    def __init__(self):

        self.imap = imaplib.IMAP4_SSL(host=self.SMTP_SERVER, port=self.SMTP_PORT)

        self.imap.login(self.USER, self.PASSWORD)


    def __enter__(self):

        self.emails = self._get_all_messages()


    def __exit__(self, exc_type, exc_value, exc_traceback):

        self.imap.close()

        self.imap.logout()


    def fetch_message(self, num=-1):

        _, data = self.imap.fetch(self.emails[num], '(RFC822)')

        _, bytes_data = data[0]

        email_message = email.message_from_bytes(bytes_data)

        return email_message


    def get_attachment(self, num=-1):

        for part in self.fetch_message(num).walk():

            if part.get_content_maintype() == 'multipart' or part.get('Content-Disposition') is None:

                continue

            if part.get_filename():

                return part.get_payload(decode=True).decode('utf-8').strip()


    def _get_all_messages(self):

        self.imap.select('Inbox')

        status, data = self.imap.search(None, 'ALL')

        return data[0].split()


查看完整回答
反对 回复 2022-10-18
  • 4 回答
  • 0 关注
  • 570 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号