如何在Python中读取电子邮件?详细示例教程

2021年11月16日19:45:08 发表评论 1,812 次浏览

了解如何使用 IMAP 协议从 Outlook、gmail 和其他电子邮件提供商中提取、解析和读取电子邮件,以及如何使用 Python 中的 imaplib 模块下载附件。

Python如何读取电子邮件?能够创建一个能够读取你的电子邮件并自动下载附件的应用程序是一个方便的工具。在本教程中,你将学习如何使用内置的imaplib模块在 Python 中列出和读取你的电子邮件,我们将需要IMAP 协议的帮助。

IMAP是电子邮件客户端用来从邮件服务器检索电子邮件消息的 Internet 标准协议。与POP3协议下载电子邮件并从服务器中删除它们(然后脱机读取它们)不同,使用IMAP,邮件不会保留在本地计算机上,而是保留在服务器上。

如何在Python中读取电子邮件?如果你想使用某种 API 而不是标准imaplib使用 Python 读取电子邮件,你可以查看有关如何使用 Gmail API的教程 ,我们将对此进行介绍。

Python读取电子邮件示例介绍和解析 - 首先,我们不需要安装任何东西,本教程中使用的所有模块都是内置的:

import imaplib
import email
from email.header import decode_header
import webbrowser
import os

# account credentials
username = "youremailaddress@provider.com"
password = "yourpassword"

def clean(text):
    # clean text for creating a folder
    return "".join(c if c.isalnum() else "_" for c in text)

我们已经导入了必要的模块,然后指定了我们电子邮件帐户的凭据。我们clean()稍后将需要该功能来创建没有空格和特殊字符的文件夹。

Python如何读取电子邮件?首先,我们需要连接到 IMAP 服务器:

# create an IMAP4 class with SSL 
imap = imaplib.IMAP4_SSL("imap.gmail.com")
# authenticate
imap.login(username, password)

由于我是在 Gmail 帐户上对此进行测试,因此我使用了imap.gmail.com服务器,请查看此链接,其中包含最常用电子邮件提供商的 IMAP 服务器列表。

此外,如果你使用的是 Gmail 帐户并且上面的代码引发了一个错误,表明凭据不正确,请确保你的帐户中允许使用安全性较低的应用程序

如果一切顺利,那么你已经成功登录到你的帐户,让我们开始接收电子邮件:

status, messages = imap.select("INBOX")
# number of top emails to fetch
N = 3
# total number of emails
messages = int(messages[0])

如何在Python中读取电子邮件?我们已经使用了imap.select()方法,它选择了一个邮箱(收件箱、垃圾邮件等),我们选择了INBOX文件夹,你可以使用imap.list()方法查看可用的邮箱。

messages变量包含该文件夹(收件箱文件夹)中的总消息数,并且status只是指示我们是否成功接收消息的消息。然后我们转换messages成一个整数,这样我们就可以创建一个for循环。

N变量是你想获取顶级的电子邮件的数量,我会用3现在,让我们在每封电子邮件消息循环,我们需要提取的一切,并完成我们的Python读取电子邮件示例代码:

for i in range(messages, messages-N, -1):
    # fetch the email message by ID
    res, msg = imap.fetch(str(i), "(RFC822)")
    for response in msg:
        if isinstance(response, tuple):
            # parse a bytes email into a message object
            msg = email.message_from_bytes(response[1])
            # decode the email subject
            subject, encoding = decode_header(msg["Subject"])[0]
            if isinstance(subject, bytes):
                # if it's a bytes, decode to str
                subject = subject.decode(encoding)
            # decode email sender
            From, encoding = decode_header(msg.get("From"))[0]
            if isinstance(From, bytes):
                From = From.decode(encoding)
            print("Subject:", subject)
            print("From:", From)
            # if the email message is multipart
            if msg.is_multipart():
                # iterate over email parts
                for part in msg.walk():
                    # extract content type of email
                    content_type = part.get_content_type()
                    content_disposition = str(part.get("Content-Disposition"))
                    try:
                        # get the email body
                        body = part.get_payload(decode=True).decode()
                    except:
                        pass
                    if content_type == "text/plain" and "attachment" not in content_disposition:
                        # print text/plain emails and skip attachments
                        print(body)
                    elif "attachment" in content_disposition:
                        # download attachment
                        filename = part.get_filename()
                        if filename:
                            folder_name = clean(subject)
                            if not os.path.isdir(folder_name):
                                # make a folder for this email (named after the subject)
                                os.mkdir(folder_name)
                            filepath = os.path.join(folder_name, filename)
                            # download attachment and save it
                            open(filepath, "wb").write(part.get_payload(decode=True))
            else:
                # extract content type of email
                content_type = msg.get_content_type()
                # get the email body
                body = msg.get_payload(decode=True).decode()
                if content_type == "text/plain":
                    # print only text email parts
                    print(body)
            if content_type == "text/html":
                # if it's HTML, create a new HTML file and open it in browser
                folder_name = clean(subject)
                if not os.path.isdir(folder_name):
                    # make a folder for this email (named after the subject)
                    os.mkdir(folder_name)
                filename = "index.html"
                filepath = os.path.join(folder_name, filename)
                # write the file
                open(filepath, "w").write(body)
                # open in the default browser
                webbrowser.open(filepath)
            print("="*100)
# close the connection and logout
imap.close()
imap.logout()

如何在Python中读取电子邮件?这里有很多内容,首先要注意的是我们使用了range(messages, messages-N, -1),这意味着从上到下,最新的电子邮件具有最高的 id 号,第一封电子邮件的 ID 为 1,这就是主要原因,如果你想提取最旧的电子邮件地址,你可以将其更改为类似range(N).

其次,我们使用了imap.fetch()方法,该方法使用RFC 822 中指定的标准格式按 ID 获取电子邮件消息。

之后,我们将fetch()方法返回的字节解析为适当的Message对象,并使用email.header模块中的decode_header()函数将电子邮件地址的主题解码为人类可读的 Unicode。

在我们打印电子邮件发件人和主题之后,我们要提取正文消息。我们查看电子邮件消息是否是多部分的,这意味着它包含多个部分。例如,电子邮件消息可以包含text/html内容和text/plain部分,这意味着它具有消息的 HTML 版本和纯文本版本。

它还可以包含文件附件,我们通过Content-Disposition标题检测到它,因此我们将它下载到为每个以主题命名的电子邮件创建的新文件夹下。

Python如何读取电子邮件?msg 对象是email模块的Message对象,还有很多其他的字段要提取,在这个例子中,我们只使用FromSubject,写msg.keys()并查看可用的字段来提取,例如,你可以获取日期使用msg[ "Date" ]发送消息的时间。

Python读取电子邮件示例输出:在我为我的测试 Gmail 帐户运行代码后,我得到了以下输出:

Subject: Thanks for Subscribing to our Newsletter !
From: example@domain.com
====================================================================================================
Subject: An email with a photo as an attachment
From: Python Code <example@domain.com>
Get the photo now!

====================================================================================================
Subject: A Test message with attachment
From: Python Code <example@domain.com>
There you have it!

====================================================================================================

因此,该代码只会打印text/plain正文消息,它会为每封电子邮件创建一个文件夹,其中包含电子邮件的附件和 HTML 版本,它还在你的默认浏览器中为提取的每封包含 HTML 的电子邮件打开 HTML 电子邮件内容。

转到我的 Gmail,我看到了用 Python 打印的相同电子邮件:

如何在Python中读取电子邮件?详细示例教程

太棒了,我还注意到为每封电子邮件创建的文件夹:

如何在Python中读取电子邮件?详细示例教程

每个文件夹现在都有 HTML 消息(如果可用)和附加到电子邮件的所有文件。

结论

Python如何读取电子邮件?现在你可以使用这个秘籍构建你自己的电子邮件客户端,例如,你可以构建一个GUI程序来像普通浏览器一样读取和解析 HTML ,而不是在新的浏览器选项卡上打开每封电子邮件,或者你可能想要每当有新电子邮件发送给你时发送通知,可能性是无限的!

但是请注意,我们还没有涵盖imaplib模块提供的所有内容,例如,你可以使用imap.search()方法搜索电子邮件并按发件人地址、主题、发送日期等进行过滤。

以下是其他 Python 电子邮件教程:

  • 如何在 Python 中发送电子邮件。
  • 如何在 Python 中删除电子邮件。
  • 如何在 Python 中使用 Gmail API。

这是用于本教程的模块的官方文档:

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: