imaplib — IMAP4 协议客户端 — Python 文档

来自菜鸟教程
Python/docs/3.8/library/imaplib
跳转至:导航、​搜索

imaplib — IMAP4 协议客户端

源代码: :source:`Lib/imaplib.py`



该模块定义了三个类,IMAP4、IMAP4_SSL 和 IMAP4_stream,它们封装了到 IMAP4 服务器的连接并实现了定义的 IMAP4rev1 客户端协议的一个大子集在 RFC 2060 中。 它向后兼容 IMAP4 (RFC 1730) 服务器,但请注意 IMAP4 不支持 STATUS 命令。

imaplib模块提供了三个类,IMAP4是基类:

class imaplib.IMAP4(host=, port=IMAP4_PORT)

这个类实现了实际的 IMAP4 协议。 在实例初始化时创建连接并确定协议版本(IMAP4 或 IMAP4rev1)。 如果未指定 host,则使用 (本地主机)。 如果省略 port,则使用标准 IMAP4 端口 (143)。

IMAP4 类支持 [X38X]with 语句。 像这样使用时,IMAP4 LOGOUT 命令会在 with 语句退出时自动发出。 例如:

>>> from imaplib import IMAP4
>>> with IMAP4("domain.org") as M:
...     M.noop()
...
('OK', [b'Nothing Accomplished. d25if65hy903weo.87'])

3.5 版更改: 添加了对 with 语句的支持。

三个例外被定义为 IMAP4 类的属性:

exception IMAP4.error
出现任何错误的异常。 异常的原因作为字符串传递给构造函数。
exception IMAP4.abort
IMAP4 服务器错误导致引发此异常。 这是 IMAP4.error 的子类。 请注意,关闭实例并实例化一个新实例通常会允许从此异常中恢复。
exception IMAP4.readonly
当服务器更改可写邮箱的状态时,会引发此异常。 这是 IMAP4.error 的子类。 其他一些客户端现在有写权限,需要重新打开邮箱才能重新获得写权限。

还有一个用于安全连接的子类:

class imaplib.IMAP4_SSL(host=, port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None)

这是一个派生自 IMAP4 的子类,它通过 SSL 加密套接字连接(要使用此类,您需要使用 SSL 支持编译的套接字模块)。 如果未指定 host,则使用 (本地主机)。 如果省略 port,则使用标准的 IMAP4-over-SSL 端口 (993)。 ssl_context 是一个 ssl.SSLContext 对象,它允许将 SSL 配置选项、证书和私钥捆绑到一个(可能是长期存在的)结构中。 请阅读 安全注意事项 以获得最佳实践。

keyfile 和 certfile 是 ssl_context 的传统替代品 - 它们可以指向用于 SSL 连接的 PEM 格式的私钥和证书链文件。 请注意,keyfile/certfile 参数与 ssl_context 互斥,如果 keyfile/ 会引发 ValueError certfile 与 ssl_context 一起提供。

3.3 版更改:添加了 ssl_context 参数。

3.4 版更改: 该类现在支持使用 ssl.SSLContext.check_hostname 和 服务器名称指示 进行主机名检查(请参阅 ssl.HAS_SNI )。

自 3.6 版起已弃用:keyfile 和 certfile 已弃用,取而代之的是 ssl_context。 请改用 ssl.SSLContext.load_cert_chain(),或让 ssl.create_default_context() 为您选择系统的可信 CA 证书。

第二个子类允许由子进程创建的连接:

class imaplib.IMAP4_stream(command)
这是从 IMAP4 派生的子类,它连接到通过将 command 传递给 subprocess.Popen() 创建的 stdin/stdout 文件描述符。

定义了以下实用函数:

imaplib.Internaldate2tuple(datestr)
解析一个 IMAP4 INTERNALDATE 字符串并返回对应的本地时间。 如果字符串格式错误,则返回值是 time.struct_time 元组或 None。
imaplib.Int2AP(num)
使用集合 [A .. 中的字符将整数转换为字节表示形式。 P]。
imaplib.ParseFlags(flagstr)
将 IMAP4 FLAGS 响应转换为单个标志的元组。
imaplib.Time2Internaldate(date_time)
将 date_time 转换为 IMAP4 INTERNALDATE 表示。 返回值是一个字符串,格式为:"DD-Mmm-YYYY HH:MM:SS +HHMM"(包括双引号)。 date_time 参数可以是一个数字(int 或 float),表示自纪元以来的秒数(由 time.time() 返回),一个 9 元组,表示本地时间 [ X184X]time.struct_time(由 time.localtime() 返回),datetime.datetime 的感知实例,或双引号字符串。 在最后一种情况下,假定已经采用正确的格式。

请注意,IMAP4 消息编号会随着邮箱的变化而变化; 特别是,在 EXPUNGE 命令执行删除后,剩余的消息将重新编号。 因此,强烈建议使用 UID 代替 UID 命令。

在模块的末尾,有一个测试部分,其中包含更广泛的使用示例。

也可以看看

华盛顿大学 IMAP 信息中心提供的描述协议的文档、实现它的服务器的来源都可以在 (Source Code) https://github.com/uw-imap/imap 找到(未维护)。


IMAP4 对象

所有 IMAP4rev1 命令都由大写或小写的同名方法表示。

命令的所有参数都转换为字符串,除了 AUTHENTICATE 和作为 IMAP4 文字传递的 APPEND 的最后一个参数。 如有必要(该字符串包含 IMAP4 协议敏感字符且未用括号或双引号括起来)每个字符串都被引用。 但是,始终引用 LOGIN 命令的 password 参数。 如果您想避免引用参数字符串(例如:STORE 的 flags 参数),则将该字符串括在括号中(例如:r'(\Deleted)')。

每个命令返回一个元组: (type, [data, ...]) 其中 type 通常是 'OK' 或 'NO',而 data 是来自命令响应,或命令的强制结果。 每个 data 要么是一个 bytes,要么是一个元组。 如果是元组,则第一部分是响应的标头,第二部分包含数据(即:“文字”值)。

下面命令的 message_set 选项是一个字符串,指定要对其执行的一个或多个消息。 它可能是一个简单的消息号 ('1')、一个消息号范围 ('2:4') 或一组由逗号分隔的非连续范围 ('1:3,6:9')。 一个范围可以包含一个星号来表示一个无限的上限 ('3:*')。

IMAP4 实例具有以下方法:

IMAP4.append(mailbox, flags, date_time, message)
将 message 附加到命名邮箱。
IMAP4.authenticate(mechanism, authobject)

验证命令 - 需要响应处理。

mechanism 指定要使用的身份验证机制 - 它应该以 AUTH=mechanism 的形式出现在实例变量 capabilities 中。

authobject 必须是可调用对象:

data = authobject(response)

它将被调用来处理服务器继续响应; 它传递的 response 参数将是 bytes。 它应该返回 bytes data,它将被 base64 编码并发送到服务器。 如果应该发送客户端中止响应 *,它应该返回 None。

3.5 版更改: 字符串用户名和密码现在编码为 utf-8 而不是仅限于 ASCII。

IMAP4.check()
服务器上的检查点邮箱。
IMAP4.close()
关闭当前选择的邮箱。 已删除的邮件将从可写邮箱中删除。 这是LOGOUT之前的推荐命令。
IMAP4.copy(message_set, new_mailbox)
将 message_set 消息复制到 new_mailbox 的末尾。
IMAP4.create(mailbox)
创建名为 mailbox 的新邮箱。
IMAP4.delete(mailbox)
删除名为 mailbox 的旧邮箱。
IMAP4.deleteacl(mailbox, who)
删除为邮箱上的 who 设置的 ACL(删除任何权限)。
IMAP4.enable(capability)

启用 功能 (请参阅 RFC 5161)。 大多数功能不需要启用。 目前仅支持 UTF8=ACCEPT 功能(参见 RFC 6855)。

3.5 版新功能:enable() 方法本身,以及 RFC 6855 支持。

IMAP4.expunge()
从选定的邮箱中永久删除已删除的项目。 为每个已删除的消息生成 EXPUNGE 响应。 返回的数据包含按接收顺序排列的 EXPUNGE 消息编号列表。
IMAP4.fetch(message_set, message_parts)
获取(部分)消息。 message_parts 应该是括号内的消息部分名称字符串,例如:"(UID BODY[TEXT])"。 返回的数据是消息部分信封和数据的元组。
IMAP4.getacl(mailbox)
获取 邮箱 的 ACL。 该方法是非标准的,但受 Cyrus 服务器支持。
IMAP4.getannotation(mailbox, entry, attribute)
为 mailbox 检索指定的 ANNOTATION。 该方法是非标准的,但受 Cyrus 服务器支持。
IMAP4.getquota(root)
获取 quota root 的资源使用和限制。 此方法是 rfc2087 中定义的 IMAP4 QUOTA 扩展的一部分。
IMAP4.getquotaroot(mailbox)
获取命名为 邮箱 的 quota roots 列表。 此方法是 rfc2087 中定义的 IMAP4 QUOTA 扩展的一部分。
IMAP4.list([directory[, pattern]])
列出 目录 中匹配 模式 的邮箱名称。 directory 默认为顶级邮件文件夹,pattern 默认匹配任何内容。 返回的数据包含 LIST 响应列表。
IMAP4.login(user, password)
使用明文密码识别客户端。 password 将被引用。
IMAP4.login_cram_md5(user, password)
识别客户端时强制使用 CRAM-MD5 身份验证以保护密码。 仅当服务器 CAPABILITY 响应包含短语 AUTH=CRAM-MD5 时才有效。
IMAP4.logout()

关闭与服务器的连接。 返回服务器 BYE 响应。

3.8 版更改: 该方法不再忽略静默任意异常。

IMAP4.lsub(directory='""', pattern='*')
以目录匹配模式列出订阅的邮箱名称。 directory 默认为顶级目录,pattern 默认匹配任何邮箱。 返回的数据是消息部分信封和数据的元组。
IMAP4.myrights(mailbox)
显示我的邮箱 ACL(即 我对邮箱拥有的权利)。
IMAP4.namespace()
返回 RFC 2342 中定义的 IMAP 命名空间。
IMAP4.noop()
将 NOOP 发送到服务器。
IMAP4.open(host, port)
在 主机 打开到 端口 的套接字。 此方法由 IMAP4 构造函数隐式调用。 该方法建立的连接对象将在IMAP4.read()、IMAP4.readline()、IMAP4.send()、中使用X147X]IMAP4.shutdown() 方法。 您可以覆盖此方法。
IMAP4.partial(message_num, message_part, start, length)
获取消息的截断部分。 返回的数据是消息部分信封和数据的元组。
IMAP4.proxyauth(user)
假设身份验证为 user。 允许授权管理员代理进入任何用户的邮箱。
IMAP4.read(size)
从远程服务器读取 size 字节。 您可以覆盖此方法。
IMAP4.readline()
从远程服务器读取一行。 您可以覆盖此方法。
IMAP4.recent()
提示服务器更新。 如果没有新消息,返回的数据为 None,否则为 RECENT 响应的值。
IMAP4.rename(oldmailbox, newmailbox)
将名为 oldmailbox 的邮箱重命名为 newmailbox。
IMAP4.response(code)
如果接收到响应 code 或 None,则返回数据。 返回给定的代码,而不是通常的类型。
IMAP4.search(charset, criterion[, ...])

在邮箱中搜索匹配的消息。 charset 可能是 None,在这种情况下,不会在对服务器的请求中指定 CHARSET。 IMAP 协议要求至少指定一个标准; 当服务器返回错误时将引发异常。 如果使用 enable() 命令启用了 UTF8=ACCEPT 功能,则 charset 必须为 None。

例子:

# M is a connected IMAP4 instance...
typ, msgnums = M.search(None, 'FROM', '"LDJ"')

# or:
typ, msgnums = M.search(None, '(FROM "LDJ")')
IMAP4.select(mailbox='INBOX', readonly=False)
选择一个邮箱。 返回的数据是 mailbox(EXISTS 响应)中的消息计数。 默认的 邮箱 是 'INBOX'。 如果设置了 readonly 标志,则不允许修改邮箱。
IMAP4.send(data)
将 data 发送到远程服务器。 您可以覆盖此方法。
IMAP4.setacl(mailbox, who, what)
为邮箱设置一个ACL。 该方法是非标准的,但受 Cyrus 服务器支持。
IMAP4.setannotation(mailbox, entry, attribute[, ...])
为 邮箱 设置 ANNOTATION。 该方法是非标准的,但受 Cyrus 服务器支持。
IMAP4.setquota(root, limits)
设置quota root的资源限制。 此方法是 rfc2087 中定义的 IMAP4 QUOTA 扩展的一部分。
IMAP4.shutdown()
关闭在 open 中建立的连接。 此方法由 IMAP4.logout() 隐式调用。 您可以覆盖此方法。
IMAP4.socket()
返回用于连接到服务器的套接字实例。
IMAP4.sort(sort_criteria, charset, search_criterion[, ...])

sort 命令是 search 的变体,具有结果的排序语义。 返回的数据包含一个空格分隔的匹配消息号列表。

Sort 在 search_criterion 参数之前有两个参数; sort_criteria 和搜索 字符集 的括号列表。 请注意,与 search 不同,搜索 charset 参数是强制性的。 还有一个uid sort命令对应sort,就像uid search对应search一样。 sort 命令首先使用 charset 参数在邮箱中搜索与给定搜索条件匹配的邮件,以解释搜索条件中的字符串。 然后它返回匹配消息的数量。

这是一个 IMAP4rev1 扩展命令。

IMAP4.starttls(ssl_context=None)

发送 STARTTLS 命令。 ssl_context 参数是可选的,应该是一个 ssl.SSLContext 对象。 这将在 IMAP 连接上启用加密。 请阅读 安全注意事项 以获得最佳实践。

3.2 版中的新功能。

在 3.4 版更改:该方法现在支持使用 ssl.SSLContext.check_hostname 和 Server Name Indication 进行主机名检查(请参阅 ssl.HAS_SNI )。

IMAP4.status(mailbox, names)
请求 邮箱 的命名状态条件。
IMAP4.store(message_set, command, flag_list)

更改邮箱中邮件的标志处置。 command 由 RFC 2060 的第 6.4.6 节指定为“FLAGS”、“+FLAGS”或“-FLAGS”之一,可选择使用“.SILENT”的后缀。

例如,要在所有消息上设置删除标志:

typ, data = M.search(None, 'ALL')
for num in data[0].split():
   M.store(num, '+FLAGS', '\\Deleted')
M.expunge()

笔记

创建包含 ']' 的标志(例如:“[test]”)违反了 RFC 3501(IMAP 协议)。 但是,imaplib 历来允许创建此类标记,并且流行的 IMAP 服务器(例如 Gmail)接受并生成此类标记。 有非 Python 程序也可以创建此类标签。 尽管它违反了 RFC 并且 IMAP 客户端和服务器应该是严格的,但出于向后兼容性的原因,imaplib 仍然允许创建此类标签,并且从 Python 3.6 开始,如果它们是从服务器发送的,则会处理它们,因为这提高现实世界的兼容性。

IMAP4.subscribe(mailbox)
订阅新邮箱。
IMAP4.thread(threading_algorithm, charset, search_criterion[, ...])

thread 命令是 search 的变体,具有结果的线程语义。 返回的数据包含一个以空格分隔的线程成员列表。

线程成员由零个或多个消息号组成,以空格分隔,表示连续的父子节点。

线程在 search_criterion 参数之前有两个参数; a threading_algorithm,和搜索字符集。 请注意,与 search 不同,搜索 charset 参数是强制性的。 还有一个uid thread命令对应thread,就像uid search对应search一样。 thread 命令首先使用 charset 参数在邮箱中搜索与给定搜索条件匹配的邮件,以解释搜索条件中的字符串。 然后它返回根据指定线程算法线程化的匹配消息。

这是一个 IMAP4rev1 扩展命令。

IMAP4.uid(command, arg[, ...])
使用由 UID 而非消息编号标识的消息执行命令参数。 返回适合命令的响应。 必须至少提供一个参数; 如果没有提供,服务器将返回错误并引发异常。
IMAP4.unsubscribe(mailbox)
退订旧邮箱。
IMAP4.xatom(name[, ...])
允许服务器在 CAPABILITY 响应中通知的简单扩展命令。

在 IMAP4 的实例上定义了以下属性:

IMAP4.PROTOCOL_VERSION
来自服务器的 CAPABILITY 响应中最新支持的协议。
IMAP4.debug
控制调试输出的整数值。 初始化值取自模块变量 Debug。 大于三个的值跟踪每个命令。
IMAP4.utf8_enabled

布尔值,通常为 False,但如果为 UTF8=ACCEPT 功能成功发出 enable() 命令,则设置为 True。

3.5 版中的新功能。


IMAP4 示例

这是一个最小的例子(没有错误检查),它打开一个邮箱并检索和打印所有消息:

import getpass, imaplib

M = imaplib.IMAP4()
M.login(getpass.getuser(), getpass.getpass())
M.select()
typ, data = M.search(None, 'ALL')
for num in data[0].split():
    typ, data = M.fetch(num, '(RFC822)')
    print('Message %s\n%s\n' % (num, data[0][1]))
M.close()
M.logout()