Skip to main content

21.15. imaplib — IMAP4协议客户端

源代码: Lib/imaplib.py


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

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

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

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

IMAP4 类支持 with 语句。当这样使用时,当 with 语句退出时,IMAP4 LOGOUT 命令自动发出。例如。:

>>> 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/certfilessl_context 一起提供,则产生 ValueError

在 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 参数可以是表示自从epoch(由 time.time() 返回)的秒的数字(int或float),表示本地时间的9元组(由 time.localtime() 返回的 time.struct_time 的实例),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 是字符串或元组。如果是元组,那么第一部分是响应的头部,第二部分包含数据(即:’literal’值)。

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

IMAP4 实例具有以下方法:

IMAP4.append(mailbox, flags, date_time, message)

message 附加到命名邮箱。

IMAP4.authenticate(mechanism, authobject)

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

mechanism 指定使用哪种认证机制 - 它应该以实例变量 capabilities 的形式显示在 AUTH=mechanism 格式中。

authobject 必须是可调用对象:

data = authobject(response)

它将被调用来处理服务器继续响应;它通过的 response 参数将是 bytes。它应该返回将被base64编码并发送到服务器的 bytes data。如果应该发送客户端中止响应 *,它应该返回 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)

删除为邮箱上的谁设置的ACL(删除任何权限)。

IMAP4.enable(capability)

启用 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)

获取 mailboxACL。该方法是非标准的,但是由 Cyrus 服务器支持。

IMAP4.getannotation(mailbox, entry, attribute)

检索 mailbox 的指定 ANNOTATION s。该方法是非标准的,但是由 Cyrus 服务器支持。

IMAP4.getquota(root)

获取 quota root 的资源使用和限制。此方法是rfc2087中定义的IMAP4 QUOTA扩展的一部分。

IMAP4.getquotaroot(mailbox)

获取名为 mailboxquota roots 的列表。此方法是rfc2087中定义的IMAP4 QUOTA扩展的一部分。

IMAP4.list([directory[, pattern]])

在符合 patterndirectory 中列出邮箱名称。 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()

返回RFC2342中定义的IMAP命名空间。

IMAP4.noop()

NOOP 发送到服务器。

IMAP4.open(host, port)

host 处打开插座到 port。此方法由 IMAP4 构造函数隐式调用。通过此方法建立的连接对象将用于 IMAP4.read()IMAP4.readline()IMAP4.send()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 响应)。默认的 mailbox'INBOX'。如果设置了 readonly 标志,则不允许修改邮箱。

IMAP4.send(data)

data 发送到远程服务器。您可以覆盖此方法。

IMAP4.setacl(mailbox, who, what)

mailbox 设置 ACL。该方法是非标准的,但是由 Cyrus 服务器支持。

IMAP4.setannotation(mailbox, entry, attribute[, ...])

mailbox 设置 ANNOTATION s。该方法是非标准的,但是由 Cyrus 服务器支持。

IMAP4.setquota(root, limits)

设置 quota root 的资源 limits。此方法是rfc2087中定义的IMAP4 QUOTA扩展的一部分。

IMAP4.shutdown()

open 中建立关闭连接。此方法由 IMAP4.logout() 隐式调用。您可以覆盖此方法。

IMAP4.socket()

返回用于连接到服务器的套接字实例。

IMAP4.sort(sort_criteria, charset, search_criterion[, ...])

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

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

这是一个 IMAP4rev1 扩展命令。

IMAP4.starttls(ssl_context=None)

发送 STARTTLS 命令。 ssl_context 参数是可选的,应为 ssl.SSLContext 对象。这将启用IMAP连接上的加密。请阅读 安全注意事项 的最佳做法。

3.2 新版功能.

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

IMAP4.status(mailbox, names)

请求 mailbox 的命名状态条件。

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 参数之前有两个参数。 threading_algorithm 和搜索 charset。注意,与 search 不同,搜索 charset 参数是强制性的。还存在与 thread 对应于 uid search 对应于 search 的方式的 uid thread 命令。 thread 命令首先在邮箱中搜索与给定搜索条件匹配的邮件,使用charset参数解释搜索条件中的字符串。然后它根据指定的线程算法返回线程化的匹配消息。

这是一个 IMAP4rev1 扩展命令。

IMAP4.uid(command, arg[, ...])

对由UID标识的消息执行命令args,而不是消息号。返回适合于命令的响应。必须提供至少一个参数;如果没有提供,服务器将返回一个错误,并将引发异常。

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