13.4.9 获取消息
使用fetch()方法,可以利用search()返回的标识符获取消息的内容(或部分内容),以便做进一步处理。这个方法有两个参数:要获取的消息ID和所获取消息的(多个)部分。message_ids参数是一个用逗号分隔的ID列表(例如,“1”,“1,2”)或者是一个ID区间 (如1:2)。message_parts参数是一个消息段名IMAP列表。与search()的搜索规则类似,IMAP协议指定了命名消息段,所以客户可以高效地获取它们真正需要的那部分消息。例如,要获取一个邮箱中消息的首部,可以使用fetch()并指定参数BODY.PEEK[HEADER]。
说明:还可以使用另一种方法获取首部(BODY[HEADERS]),不过这种形式有一个副作用,会隐式地将消息标志为已读,而在很多情况下并不希望如此。
import imaplib
import pprint
import imaplib_connect
imaplib.Debug = 4
with imaplib_connect.open_connection() as c:
c.select('INBOX',readonly=True)
typ,msg_data = c.fetch('1','(BODY.PEEK[HEADER] FLAGS)')
pprint.pprint(msg_data)
在这个例子中,fetch()的返回值已经被部分解析,所以与list()的返回值相比,从某种程度上讲会更难处理。可以打开调试来显示客户与服务器之间完整的交互,以理解为什么会这样。
FETCH命令的响应中,首先是标志,然后指示有595字节的首部数据。客户用这个消息响应构造一个元组,然后用一个包含右括号())的字符串(服务器在获取命令响应的最后会发送这个字符串)借宿这个序列。由于采用了这种格式,就能更容易地单独获取信息的不同部分,或者重新组合响应并在客户端解析。
import imaplib
import pprint
import imaplib_connect
with imaplib_connect.open_connection() as c:
c.select('INBOX',readonly=True)
print('HEADER:')
typ,msg_data = c.fetch('1','(BODY.PEEK[HEADER])')
for response_part in msg_data:
if isinstance(response_part,tuple):
print(response_part[1])
print('\nBODY TEXT:')
typ,msg_data = c.fetch('1','(BODY.PEEK[TEXT])')
for response_part in msg_data:
if isinstance(response_part,tuple):
print(response_part[1])
print('\nFLAGS:')
typ,msg_data = c.fetch('1','(FLAGS)')
for response_part in msg_data:
print(response_part)
print(imaplib.ParseFlags(response_part))
单独地获取值还有一个额外的好处,这样可以很容易地使用ParseFlags()解析响应中的标志。