python取信和附件。

#!/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()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值