imaplib
--- IMAP4 协议客户端¶
源代码: Lib/imaplib.py
此模块定义了三个类 IMAP4
、IMAP4_SSL
和 IMAP4_stream
,它们封装了与 IMAP4 服务器的连接,并实现了 RFC 2060 中定义的大部分 IMAP4rev1 客户端协议。它向后兼容 IMAP4 (RFC 1730) 服务器,但请注意 IMAP4 不支持 STATUS
命令。
可用性:非 WASI。
此模块在 WebAssembly 上不起作用或不可用。有关更多信息,请参阅 WebAssembly 平台。
- class imaplib.IMAP4(host='', port=IMAP4_PORT, timeout=None)¶
该类实现了实际的 IMAP4 协议。在实例初始化时创建连接并确定协议版本(IMAP4 或 IMAP4rev1)。如果未指定 host,则使用
''
(本地主机)。如果省略 port,则使用标准的 IMAP4 端口(143)。可选的 timeout 参数指定连接尝试的超时时间(以秒为单位)。如果未给出 timeout 或其值为None
,则使用全局默认套接字超时时间。IMAP4
类支持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
语句的支持。在 3.9 版更改: 添加了可选的 timeout 参数。
IMAP4
类定义了三个异常作为其属性。
- exception IMAP4.error¶
在出现任何错误时引发的异常。异常的原因作为字符串传递给构造函数。
- exception IMAP4.abort¶
IMAP4 服务器错误会导致此异常被引发。这是
IMAP4.error
的一个子类。请注意,关闭实例并实例化一个新的实例通常可以从此异常中恢复。
- exception IMAP4.readonly¶
当可写邮箱的状态被服务器更改时,会引发此异常。这是
IMAP4.error
的一个子类。现在有其他客户端拥有写权限,需要重新打开邮箱以重新获取写权限。
还有一个用于安全连接的子类
- class imaplib.IMAP4_SSL(host='', port=IMAP4_SSL_PORT, *, ssl_context=None, timeout=None)¶
这是派生自
IMAP4
的一个子类,它通过 SSL 加密的套接字进行连接(要使用此类,需要一个编译时带有 SSL 支持的 socket 模块)。如果未指定 host,则使用''
(本地主机)。如果省略 port,则使用标准的 IMAP4-over-SSL 端口(993)。ssl_context 是一个ssl.SSLContext
对象,它允许将 SSL 配置选项、证书和私钥捆绑到一个(可能长期存在的)结构中。请阅读 安全考量 以了解最佳实践。可选的 timeout 参数指定连接尝试的超时时间(以秒为单位)。如果未给出 timeout 或其值为
None
,则使用全局默认套接字超时时间。在 3.3 版更改: 添加了 ssl_context 参数。
在 3.4 版更改: 该类现在支持通过
ssl.SSLContext.check_hostname
进行主机名检查和*服务器名称指示*(参见ssl.HAS_SNI
)。在 3.9 版更改: 添加了可选的 timeout 参数。
在 3.12 版更改: 已移除已弃用的 keyfile 和 certfile 参数。
第二个子类允许由子进程创建连接
- 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 参数可以是一个表示自纪元以来秒数的数字(整数或浮点数,如time.time()
所返回),一个表示本地时间的 9 元组,一个time.struct_time
实例(如time.localtime()
所返回),一个带时区的datetime.datetime
实例,或一个带双引号的字符串。在最后一种情况下,假定它已经是正确的格式。
请注意,IMAP4 邮件编号会随着邮箱的更改而改变;特别是在 EXPUNGE
命令执行删除操作后,剩余的邮件会重新编号。因此,强烈建议使用 UID 命令来代替,使用 UID。
模块末尾有一个测试部分,其中包含更广泛的用法示例。
参见
描述协议的文档、实现该协议的服务器源码,均可在华盛顿大学 IMAP 信息中心找到(**源代码**)https://github.com/uw-imap/imap(**已不再维护**)。
IMAP4 对象¶
所有 IMAP4rev1 命令都由同名的方法表示,无论是大写还是小写。
命令的所有参数都会被转换为字符串,除了 AUTHENTICATE
,以及 APPEND
的最后一个参数,该参数作为 IMAP4 字面量传递。如果必要(字符串包含 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 指定要使用的认证机制——它应出现在实例变量
capabilities
中,形式为AUTH=mechanism
。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 在 mailbox 上设置的 ACL(移除任何权限)。
- IMAP4.expunge()¶
从选定的邮箱中永久删除已删除的项目。为每个已删除的消息生成一个
EXPUNGE
响应。返回的数据包含一个按接收顺序列出的EXPUNGE
消息编号列表。
- IMAP4.fetch(message_set, message_parts)¶
获取消息(的部分)。message_parts 应该是一个用括号括起来的消息部分名称字符串,例如:
"(UID BODY[TEXT])"
。返回的数据是消息部分信封和数据的元组。
- IMAP4.getacl(mailbox)¶
获取 mailbox 的
ACL
。该方法非标准,但Cyrus
服务器支持。
- IMAP4.getannotation(mailbox, entry, attribute)¶
检索 mailbox 的指定
ANNOTATION
s。该方法非标准,但Cyrus
服务器支持。
- IMAP4.getquota(root)¶
获取
quota
root 的资源使用情况和限制。该方法是 rfc2087 中定义的 IMAP4 QUOTA 扩展的一部分。
- IMAP4.getquotaroot(mailbox)¶
获取指定 mailbox 的
quota
roots
列表。该方法是 rfc2087 中定义的 IMAP4 QUOTA 扩展的一部分。
- IMAP4.idle(duration=None)¶
返回一个
Idler
:一个可迭代的上下文管理器,实现了 RFC 2177 中定义的 IMAP4IDLE
命令。返回的对象在被
with
语句激活时发送IDLE
命令,通过 迭代器 协议产生 IMAP 未标记响应,并在上下文退出时发送DONE
。所有在发送
IDLE
命令后到达的未标记响应(包括在服务器确认该命令之前到达的任何响应)都可以通过迭代获得。任何剩余的响应(那些在with
上下文中未迭代的响应)可以在IDLE
结束后通过IMAP4.response()
以常规方式检索。响应表示为
(type, [data, ...])
元组,如 IMAP4 Objects 中所述。duration 参数设置一个最大空闲持续时间(以秒为单位),超过该时间后任何正在进行的迭代将停止。它可以是
int
或float
,或者None
表示没有时间限制。希望避免在施加不活动超时的服务器上超时的调用者应将其保持在最多 29 分钟(1740 秒)。需要套接字连接;在IMAP4_stream
连接上,duration 必须为None
。>>> with M.idle(duration=29 * 60) as idler: ... for typ, data in idler: ... print(typ, data) ... EXISTS [b'1'] RECENT [b'1']
- Idler.burst(interval=0.1)¶
产生一组响应,这些响应的间隔不超过 interval 秒(表示为
int
或float
)。这个 生成器 是逐个迭代响应的替代方案,旨在帮助高效的批处理。它检索下一个响应以及任何立即可用的后续响应。(例如,在批量删除后快速出现的一系列
EXPUNGE
响应。)需要套接字连接;在
IMAP4_stream
连接上不起作用。>>> with M.idle() as idler: ... # get a response and any others following by < 0.1 seconds ... batch = list(idler.burst()) ... print(f'processing {len(batch)} responses...') ... print(batch) ... processing 3 responses... [('EXPUNGE', [b'2']), ('EXPUNGE', [b'1']), ('RECENT', [b'0'])]
提示
在等待一批响应中的第一个响应时,会遵守传递给
IMAP4.idle()
的IDLE
上下文的最大持续时间。因此,一个已过期的Idler
将导致此生成器立即返回而不产生任何内容。如果在循环中使用它,调用者应考虑这一点。
备注
IMAP4.idle()
返回的迭代器只能在with
语句中使用。在该上下文之前或之后,每当命令完成时,未经请求的响应会在内部收集,并可以使用IMAP4.response()
检索。备注
Idler
类名和结构是内部接口,可能会发生变化。调用代码可以依赖于其上下文管理、迭代和公共方法的稳定性,但不应子类化、实例化、比较或以其他方式直接引用该类。在 3.14 版本加入。
- IMAP4.list([directory[, pattern]])¶
列出 directory 中与 pattern 匹配的邮箱名称。directory 默认为顶级邮件文件夹,pattern 默认为匹配任何内容。返回的数据包含一个
LIST
响应的列表。
- IMAP4.login(user, password)¶
使用明文密码标识客户端。password 将被加上引号。
- IMAP4.login_cram_md5(user, password)¶
在向客户端标识时强制使用
CRAM-MD5
身份验证以保护密码。仅当服务器CAPABILITY
响应包含短语AUTH=CRAM-MD5
时才有效。在 3.14 版更改: 如果 MD5 支持不可用,则会引发
IMAP4.error
。
- IMAP4.logout()¶
关闭与服务器的连接。返回服务器的
BYE
响应。在 3.8 版更改: 该方法不再静默地忽略任意异常。
- IMAP4.lsub(directory='""', pattern='*')¶
列出目录中与模式匹配的已订阅邮箱名称。*directory* 默认为顶级目录,*pattern* 默认为匹配任何邮箱。返回的数据是消息部分信封和数据的元组。
- IMAP4.myrights(mailbox)¶
显示我对一个邮箱的ACLs(即我在该邮箱上的权限)。
- IMAP4.noop()¶
向服务器发送
NOOP
。
- IMAP4.open(host, port, timeout=None)¶
在 host 上打开到 port 的套接字。可选的 timeout 参数指定了连接尝试的超时秒数。如果没有给出 timeout 或者为
None
,则使用全局默认套接字超时。另请注意,如果将 timeout 参数设置为零,则会引发ValueError
来拒绝创建非阻塞套接字。此方法由IMAP4
构造函数隐式调用。由此方法建立的连接对象将在IMAP4.read()
,IMAP4.readline()
,IMAP4.send()
和IMAP4.shutdown()
方法中使用。您可以重写此方法。引发一个参数为
self
,host
,port
的 审计事件imaplib.open
。在 3.9 版更改: 添加了 timeout 参数。
- 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.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 参数是强制性的。还有一个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
进行主机名检查和*服务器名称指示*(参见ssl.HAS_SNI
)。
- IMAP4.status(mailbox, names)¶
为 mailbox 请求指定名称的状态条件。
- 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
的一个变体,对结果具有线程化语义。返回的数据包含一个以空格分隔的线程成员列表。线程成员由零个或多个消息编号组成,由空格分隔,表示连续的父级和子级。
Thread 在 search_criterion 参数之前有两个参数:一个 threading_algorithm,和搜索用的 charset。请注意,与
search
不同,搜索用的 charset 参数是强制性的。还有一个uid thread
命令,它与thread
的关系就像uid search
与search
的关系一样。thread
命令首先使用 charset 参数来解释搜索标准中的字符串,在邮箱中搜索与给定搜索标准匹配的消息。然后,它返回根据指定的线程化算法进行线程化的匹配消息。这是一个
IMAP4rev1
扩展命令。
- IMAP4.uid(command, arg[, ...])¶
使用 UID 而不是消息编号来标识消息,执行命令参数。返回与命令相适应的响应。至少必须提供一个参数;如果没有提供,服务器将返回一个错误并引发异常。
- IMAP4.unsubscribe(mailbox)¶
从旧邮箱退订。
- IMAP4.unselect()¶
imaplib.IMAP4.unselect()
释放与所选邮箱关联的服务器资源,并使服务器返回到已验证状态。此命令执行与imaplib.IMAP4.close()
相同的操作,不同之处在于不会从当前选定的邮箱中永久删除任何消息。在 3.9 版本中新增。
- IMAP4.xatom(name[, ...])¶
允许服务器在
CAPABILITY
响应中通知的简单扩展命令。
在 IMAP4
的实例上定义了以下属性:
- IMAP4.PROTOCOL_VERSION¶
服务器
CAPABILITY
响应中最新的受支持协议。
- IMAP4.debug¶
用于控制调试输出的整数值。初始值取自模块变量
Debug
。大于三的值会跟踪每个命令。
IMAP4 示例¶
这是一个最小的示例(没有错误检查),它打开一个邮箱并检索和打印所有消息:
import getpass, imaplib
M = imaplib.IMAP4(host='example.org')
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()