目录
1 POP
POP(Post Office Protocol,邮局协议):用于电子邮件的接收。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。POP最大的优点是简单(执行邮件fetch,delete),这同时也是它最大的缺点(无法辨别已下载的邮件,即客户端和服务器的同步;IMPA可以解决这个问题)。
IMAP在POP基础上提供更多的功能,本文简单介绍POP。对于IMAP的介绍,请见这里
如今最流行的POP版本是3,因此我们常默认POP就是POP3。
Python的21.14 poplib的是对POP3协议的client实现,主要提供连接POP server,mailbox信息收集,下载messages,删除server原始message等4个功能。
1.1 Pop Server Compatibility
POP服务端的实现在POP标准里并没有指明,因此对于如何同步非常模糊,有些POP服务端只有当你下载才认为是已读,有些即使下载也不认为是已读。因此在使用POP3的时候要格外小心。
1.2 Connecting and Authenticating
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import getpass, poplib, sys
def main():
if len(sys.argv) !=3:
print("usage: {} hostname username".format(sys.argv[0]))
sys.exit(2)
hostname, username = sys.argv[1:]
p = poplib.POP3(hostname)
try:
p.user(username)
p.pass_(getpass.getpass())
except poplib.error_proto as e:
print("Login fail: {}".format(e))
else:
print("Your message: {}".format(p.stat()))
finally:
p.quit()
if __name__=="__main__":
main()
1.3 Obtaining Mailbox Information
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import getpass, poplib, sys
def main():
if len(sys.argv) != 3:
print('usage: %s hostname username' % sys.argv[0])
exit(2)
hostname, username = sys.argv[1:]
passwd = getpass.getpass()
p = poplib.POP3_SSL(hostname)
try:
p.user(username)
p.pass_(passwd)
except poplib.error_proto as e:
print("Login failed:", e)
else:
response, listings, octet_count = p.list()
if not listings:
print("No messages")
for listing in listings:
number, size = listing.decode('ascii').split()
print("Message %s has %s bytes" % (number, size))
finally:
p.quit()
if __name__ == '__main__':
main()
1.4 Downloading and Deleting Messages
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import email, getpass, poplib, sys
def main():
if len(sys.argv) != 3:
print('usage: %s hostname username' % sys.argv[0])
exit(2)
hostname, username = sys.argv[1:]
passwd = getpass.getpass()
p = poplib.POP3_SSL(hostname)
try:
p.user(username)
p.pass_(passwd)
except poplib.error_proto as e:
print("Login failed:", e)
else:
visit_all_listings(p)
finally:
p.quit()
def visit_all_listings(p):
response, listings, octets = p.list()
for listing in listings:
visit_listing(p, listing)
def visit_listing(p, listing):
number, size = listing.decode('ascii').split()
print('Message', number, '(size is', size, 'bytes):')
print()
response, lines, octets = p.top(number, 0)
document = '\n'.join( line.decode('ascii') for line in lines )
message = email.message_from_string(document)
for header in 'From', 'To', 'Subject', 'Date':
if header in message:
print(header + ':', message[header])
print()
print('Read this message [ny]?')
answer = input()
if answer.lower().startswith('y'):
response, lines, octets = p.retr(number)
document = '\n'.join( line.decode('ascii') for line in lines )
message = email.message_from_string(document)
print('-' * 72)
for part in message.walk():
if part.get_content_type() == 'text/plain':
print(part.get_payload())
print('-' * 72)
print()
print('Delete this message [ny]?')
answer = input()
if answer.lower().startswith('y'):
p.dele(number)
print('Deleted.')
if __name__ == '__main__':
main()