Python用IMAP接收邮件

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Python⽤IMAP接收邮件
⼀、简介
IMAP(Internet Message Access Protocol),这个协议与POP⼀样,也是从邮件服务器上下载邮件到本机,不过IMAP⽐POP的功能要更加强⼤些,IMAP除⽀持POP所有功能外,还⽀持以下功能:
多个邮件⽂件夹(收件箱、发件箱、垃圾邮件...)
IMAP服务器上进⾏标记如:Seen, Replied, Read, Deleted
在服务器端的⽂件夹之间拷贝和移动邮件
...
这样,virtualenv已经安装好。

下⾯需要创建虚拟环境实例,步骤如下:
$ virtualenv --no-site-packages myenv
$ cd myenv
2. 安装IMAPClient
myenv 为⾃⼰定义的虚拟环境的名字。

这样,我们已经在myenv⾥⾯,接下来就可⼀安装IMAPClient包了。

步骤如下:
$ sudo pip install imapclient
$ python -c 'import imapclient'
此时,可以在python下使⽤imapclient模块,但是不能在python3下使⽤,在⽹上查了⼀些资料,尤其是看了上⾯的那个介绍virtualenv 的⽹页,没找到有⽤的,但是,回头发现,这个imapclient是好使的了,不⽤进⼊gmapenv,直接使⽤即可,got it!
注意,上⾯⽤到了pip⼯具,如果没有的话⼀定要安装啊。

$ sudo apt-get install pip
三、开始正式学习IMAP
1. 因为可能会出现中⽂,因此在程序的最上⾯,必须加上如下代码:
#-*- encoding: utf-8 -*-
#-*- encoding: gbk -*-
2. 所需模块
import getpass, email, sys
from imapclient import IMAPClient
3. 连接服务、登录账户
这⼀步也没什么好讲的。

代码如下:
# 通过以下⽅式连接smtp服务器,没有考虑异常情况,详细请参考官⽅⽂档
c = IMAPClient(hostname = '', ssl= True)
try:
c.login(username, passwd) #登录个⼈帐号
except c.Error:
print('Could not log in')
sys.exit(1)
4. 进⼊收件箱,查看未读邮件
c.select_folder('INBOX', readonly = True)
result = c.search('UNSEEN')
利⽤函数进⾏⽂件夹,'INBOX'为收件箱,readonly = True 表明只读并不修改任何信息
利⽤函数选择想要的邮件,'UNSEEN'是邮件的flag,关于邮件的flag就不特别说明了,返回邮件的message-id
5. 有了未读邮件的ID(result),下⾯利⽤fetch()函数将邮件取来(下载到本机)
msgdict = c.fetch(result, ['BODY.PEEK[]'] )
通过fetch()函数取得邮件内容,fetch()的详细介绍请见
fetch(self, message, data) 其中self参数可忽略,message为message_id, data 的作⽤是抓取message中的哪些部分。

官⽅⽂档中没有给出data的其他可选的参数,我⼀开始怎么都不找到,最终在中进⾏提问,⼀位⼤哥把介绍给我,在 6.4.5 FETCH Command 。

这⾥⾯⾮常详细的介绍了各个函数的各种细节,当然也可以查到data其他可选的参数 6.4.5 表⽰的是原书的节。

特别感谢这位哥们,⼈类的⼒量是⽆穷的啊!
我们只需要'BODY.PEEK[]'即可。

6. 已经把邮件取出,下⾯开始解析邮件
for message_id, message in msgdict.items():
e = email.message_from_string(message['BODY[]']) # ⽣成Message类型
7. 得到的 e 即为Message类型的邮件,先⾯开始将⼜将中解析出'From', 'Subject'
subject = email.header.make_header(email.header.decode_header(e['SUBJECT'])) #必须保证包含subject
mail_from = email.header.make_header(email.header.decode_header(e['From']))
8. 从Message e中解析出content正⽂
同上⼀篇的POP⼀样,根据get_payload()返回的不同类型,选择解析⽅法,代码如下:
maintype = e.get_content_maintype()
if maintype == 'multipart':
for part in e.get_payload():
if part.get_content_maintype() == 'text':
mail_content = part.get_payload(decode=True).strip()
elif maintype == 'text':
mail_content = e.get_payload(decode=True).strip()
# 此时,需要把content转化成中⽂,利⽤如下⽅法:
try:
mail_content = mail_content.decode('gbk')
except UnicodeDecodeError:
print('decode error')
sys.exit(1)
9. ⾄此,我们已经完成了查看是否有未读邮件。

如果有的话将未读邮件的'From', 'Subject', content解析出来。

正如上⾯完成的 mail_from, subject, mail_content⼀样,现在可以完美的显⽰,即使有中⽂!
四、完整代码
#-*- encoding: utf-8 -*-
#-*- encoding: gbk -*-
# 因为可能会⽤到中⽂,所以必须有上⾯的这两句话
# 引⼊模块及IMAPClient类
import getpass, email, sys
from imapclient import IMAPClient
hostname = '' #gmail的smtp服务器⽹址
username = 'myUserName@'
passwd = '***'
c = IMAPClient(hostname, ssl= True) # 通过⼀下⽅式连接smtp服务器,没有考虑异常情况,详细请参考官⽅⽂档
try:
c.login(username, passwd) #登录个⼈帐号
except c.Error:
print('Could not log in')
sys.exit(1)
else:
c.select_folder('INBOX', readonly = True)
# 利⽤select_folder()函数进⾏⽂件夹,'INBOX'为收件箱,readonly = True 表明只读并不修改任何信息
result = c.search('UNSEEN')
msgdict = c.fetch(result, ['BODY.PEEK[]'] )
# 现在已经把邮件取出来了,下⾯开始解析邮件
for message_id, message in msgdict.items():
e = email.message_from_string(message['BODY[]']) # ⽣成Message类型
# 由于'From', 'Subject' header有可能有中⽂,必须把它转化为中⽂
subject = email.header.make_header(email.header.decode_header(e['SUBJECT']))
mail_from = email.header.make_header(email.header.decode_header(e['From']))
# 解析邮件正⽂
maintype = e.get_content_maintype()
if maintype == 'multipart':
for part in e.get_payload():
if part.get_content_maintype() == 'text':
mail_content = part.get_payload(decode=True).strip()
elif maintype == 'text':
mail_content = e.get_payload(decode=True).strip()
# 此时,需要把content转化成中⽂,利⽤如下⽅法:
try:
mail_content = mail_content.decode('gbk')
except UnicodeDecodeError:
print('decode error')
sys.exit(1)
else:
print('new message')
print('From: ', mail_from)
print('Subject: ', subject)
getstr = input('if you wanna read it, input y: ')
if getstr.startswith('y'):
print('-'*10, 'mail content', '-'*10)
print(mail_content.replace('<br>', '\n'))
print('-'*10, 'mail content', '-'*10)
finally:
c.logout()
五、总结
⾄此,我们已经学习了利⽤Python编写邮件服务的所有⾮常基本的内容,由于我的需求不是很⾼,⽬标不是做成⼀个功能强⼤的邮箱客户端,所以诸如:MIME、附件、图⽚等功能都没有学习,当然也没有介绍。

因为我们现在接收的邮件,⼤多数都是MIME格式的,不过上⽂的包含了点解析MIME格式邮件的代码。

详细请参考Chaper E-mail Composition and Decoding。

相关文档
最新文档