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

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

21.15. 映射库 — IMAP4 协议客户端

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



该模块定义了三个类,IMAP4IMAP4_SSLIMAP4_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 配置选项、证书和私钥捆绑到一个(可能是长期存在的)结构中。 请阅读 安全注意事项 以获得最佳实践。

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

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

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

自 3.6 版起已弃用:keyfilecertfile 已弃用,取而代之的是 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 信息中心 (https://www.washington.edu/imap/ ])。


21.15.1. IMAP4 对象

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

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

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

下面命令的 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 响应。
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)
如果接收到响应 codeNone,则返回数据。 返回给定的代码,而不是通常的类型。
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)
选择一个邮箱。 返回的数据是 mailboxEXISTS 响应)中的消息计数。 默认的 邮箱'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_hostnameServer Name Indication 进行主机名检查(请参阅 ssl.HAS_SNI )。

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

更改邮箱中邮件的标志处置。 commandRFC 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 版中的新功能。


21.15.2. 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()