#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by LiTianYao on 2018/3/6
#
import getpass
import email
import sys
from future.backports.email.header import decode_header
from imapclient import IMAPClient
class Imapmail(object):
def __init__(self): # 初始化数据
self.serveraddress = None
self.user = None
self.passwd = None
self.prot = None
self.ssl = None
self.timeout = None
self.savepath = None
self.server = None
def client(self): # 链接
try:
self.server = IMAPClient(
self.serveraddress,
self.prot,
self.ssl,
timeout=self.timeout)
return self.server
except BaseException as e:
return "ERROR: >>> " + str(e)
def login(self): # 认证
try:
self.server.login(self.user, self.passwd)
except BaseException as e:
return "ERROR: >>> " + str(e)
# 获取目录列表 [((), b'/', 'INBOX'), ((b'\\Drafts',), b'/', '草稿箱'),]
def getmaildir(self):
dirlist = self.server.list_folders()
return dirlist
def getallmail(self): # 收取所有邮件
print(self.server)
# 选择目录 readonly=True 只读,不修改,这里只选择了 收件箱
self.server.select_folder('INBOX', readonly=True)
'''
SELECT <folder>:SELECT命令让Client选定某个邮箱(Folder),表示即将对该邮箱(Folder)内的邮件作操作。邮箱标志的当前状态也返回给了用户,同时返回的还有一些关于邮件和邮箱的附加信息。
C: A142 SELECT INBOX
S: * 172 EXISTS
S: * 1 RECENT
S: * OK [UNSEEN 12] Message 12 is first unseen
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
S: A142 OK [READ-WRITE] SELECT completed
'''
result = self.server.search() # 获取所有邮件总数目 [1,2,3,....]
print((result)) #通知有多少个信
'''
FETCH <mail id><datanames>:FETCH 命令用于读取邮件的文本信息,且仅用于显示的目的。包含两个参数,messageset:表示希望读取的邮件号列表,IAMP服务器邮箱中的每个邮件都有 一个唯一的ID标识,(邮件号列表参数可以是一个邮件号,也可以是由逗号分隔的多个邮件号,或者由冒号间隔的一个范围),IMAP服务器返回邮件号列表中 全部邮件的指定数据项内容。
数据名参数确定能够被独立返回的邮件的一部分,下面我们看看各参数返回的邮件信息:
ALL:只返回按照一定格式的邮件摘要,包括邮件标志、RFC822.SIZE、自身的时间和信封信息。IMAP客户机能够将标准邮件解析成这些信息并显示出来。
BODY:只返回邮件体文本格式和大小的摘要信息。IMAP客户机可以识别这些细腻,并向用户显示详细的关于邮件的信息。其实是一些非扩展的BODYSTRUCTURE的信息。
FAST:只返回邮件的一些摘要,包括邮件标志、RFC822.SIZE、和自身的时间。
FULL:同样的还是一些摘要信息,包括邮件标志、RFC822.SIZE、自身的时间和BODYSTRUCTURE的信息。
BODYSTRUCTUR: 是邮件的[MIME-IMB]的体结构。这是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段和[MIME-IMB]头信息得出来 的。包括的内容有:邮件正文的类型、字符集、编码方式等和各附件的类型、字符集、编码方式、文件名称等等。
ENVELOPE:信息的信封结构。是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段得出来的,默认各字段都是需要的。主要包括:自身的时间、附件数、收件人、发件人等。
FLAGS:此邮件的标志。
INTERNALDATE:自身的时间。
RFC822.SIZE:邮件的[RFC-2822]大小
RFC822.HEADER:在功能上等同于BODY.PEEK[HEADER],
RFC822:功能上等同于BODY[]。
RFC822.TEXT:功能上等同于BODY[TEXT]
UID:返回邮件的UID号,UID号是唯一标识邮件的一个号码。
BODY[section] <<partial>>:返回邮件的中的某一指定部分,返回的部分用section来表示,section部分包含的信息通常是 代表某一部分的一个数字或者是下面的某一个部分:HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。如果section部分是空的话,那就代表返回全部的信息,包括头信息。
BODY[HEADER]返回完整的文件头信息。
BODY[HEADER.FIELDS ()]:在小括号里面可以指定返回的特定字段。
BODY[HEADER.FIELDS.NOT ()]:在小括号里面可以指定不需要返回的特定字段。
BODY[MIME]:返回邮件的[MIME-IMB]的头信息,在正常情况下跟BODY[HEADER]没有区别。
BODY[TEXT]:返回整个邮件体,这里的邮件体并不包括邮件头。
'''
data = self.server.fetch(1, ['ENVELOPE']) #信息的信封结构。是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段得出来的,默认各字段都是需要的。主要包括:自身的时间、附件数、收件人、发件人等。
size = self.server.fetch(1, ['RFC822.SIZE'])
print("大小", size)
print(data[1])
envelope = data[1][b'ENVELOPE']
print(envelope)
subject = envelope.subject.decode()
print(subject)
subject, de = decode_header(subject)[0]
subject = subject if not de else subject.decode(de)
print(subject,de)
msgdict = self.server.fetch(1, ['BODY[]']) # 获取邮件内容
mailbody = msgdict[1][b'BODY[]'] # 获取邮件内容
print(msgdict)
print('------------body------------')
print(mailbody)
msg = email.message_from_string(str(mailbody, encoding=de))
print(type(msg))
print(msg.get('subject'))
print(email.utils.parseaddr(msg.get("from"))[1])
print(email.utils.parseaddr(msg.get("to"))[1])
# 循环信件中的每一个mime的数据块
for part in msg.walk():
# 这里要判断是否是multipart,是的话,里面的数据是一个message 列表
if not part.is_multipart():
charset = part.get_charset()
# print 'charset: ', charset
contenttype = part.get_content_type()
# print 'content-type', contenttype
name = part.get_param("name") # 如果是附件,这里就会取出附件的文件名
if name:
pass
# 有附件
# 下面的三行代码只是为了解码像 =?gbk?Q?=CF=E0=C6=AC.rar?=这样的文件名
attach_data = part.get_payload(decode=True) # 解码出附件数据,然后存储到文件中
try:
f = open(name, 'wb') #注意一定要用wb来打开文件,因为附件一般都是二进制文件
except:
# print '附件名有非法字符,自动换一个'
f = open('aaaa', 'wb')
f.write(attach_data)
# f.close()
else:
# 不是附件,是文本内容
print(part.get_payload(decode=True)) # 解码出文本内容,直接输出来就可以了。
# pass
# print '+'*60 # 用来区别各个部分的输出
filename = str('test1') + ".eml"
f = open(filename, 'w')
f.write(str(msg))
f.close
def close(self):
self.server.close
if __name__ == "__main__":
imap = Imapmail()
imap.serveraddress = "imap.qq.com" # 邮箱地址
imap.user = "sdzylw@qq.com" # 邮箱密码
imap.passwd = "lwkbpffswzyjbbij" # 邮箱账号
imap.savepath = "" # 邮件存放路径
imap.client()
imap.login()
imap.getallmail()
# imap.close()
python取信和附件。
最新推荐文章于 2024-04-18 08:55:27 发布