鱼C论坛

 找回密码
 立即注册
查看: 2896|回复: 8

[已解决]python根据邮件的接收时间来下载指定附件

[复制链接]
发表于 2019-11-26 14:43:28 | 显示全部楼层 |阅读模式
100鱼币
本帖最后由 shenshuai 于 2019-11-27 01:03 编辑

大佬们,我在网上找到一个可以输入指定的标题下载附件。但是这里面有个问题,如果一个人发了很多标题一样的邮件很多次,那这个程序就会下载所有的附件。
我现在想把这段代码改一下, 改成按照时间顺序来下载。下载这个标题下最新时间的附件,应该怎么做啊?
这是代码:
def decode_str(s):
    if not s:
        return None
    value, charset = decode_header(s)[0]
    if charset:
        value = value.decode(charset)
    return value

def get_mails(prefix):
    host = 'pop.qq.com'  
    username = 'email '  
    password = 'password'  
      
    server = poplib.POP3(host)
    server.user(username)
    server.pass_(password)
    # 获得邮件
    messages = [server.retr(i) for i in range(1, len(server.list()[1]) + 1)]  
    messages = [b'\r\n'.join(mssg[1]).decode() for mssg in messages]  
    messages = [Parser().parsestr(mssg) for mssg in messages]  
    print("===="*10)
    messages = messages[::-1]
    for message in messages:  
        subject = message.get('Subject')
        subject = decode_str(subject)
        #如果标题匹配
        if subject and subject[:len(prefix)] == prefix:
            value = message.get('From')
            if value:
                hdr, addr = parseaddr(value)
                name = decode_str(hdr)
                value = u'%s <%s>' % (name, addr)
            print("发件人: %s" % value)
            print("标题:%s" % subject)
            for part in message.walk():  
                fileName = part.get_filename()  
                fileName = decode_str(fileName)
                # 保存附件  
                if fileName:  
                    with open(fileName, 'wb') as fEx:
                        data = part.get_payload(decode=True) 
                        fEx.write(data)  
                        print("附件%s已保存" % fileName)
    server.quit()  

if __name__ == '__main__':
    prefix = 'first demo'
    get_mails(prefix)
最佳答案
2019-11-26 14:43:29
本帖最后由 XiaoPaiShen 于 2019-11-28 03:28 编辑

我用 imaplib 实现了下载最新标题的功能,只是我无法在QQ邮箱测试,你试试运行对不对
import imaplib
import email

from email.header import decode_header

class Email_Checker:
    def __init__(self, email='', password='', server='imap.gmail.com'):
        self.server = server
        self.email = email
        self.password = password

        self.mail = imaplib.IMAP4_SSL(self.server)
        self.mail.login(self.email, self.password)
        self.mail.select('inbox')

        self.mail_content = {'plain': None, 'html': None}
        self.mail_messages = list()

    def decode_content(self, content):
        if not content:
            return None

        value, charset = decode_header(content)[0]
        if charset:
            value = value.decode(charset)
        return value    

    def filter_mails(self, title):
        status, data = self.mail.uid('search', None, "ALL")
        email_uids = data[0].split()
        for uid in email_uids:
            status, content = self.mail.uid('fetch', uid, '(RFC822)')
            raw_email = content[0][1]
            message = email.message_from_bytes(raw_email)
            mail_subject = message['subject']

            if mail_subject == title:
                self.mail_messages.append(message)

    def get_content(self, message):
        for part in message.walk():
            if part.is_multipart:
                content_type = part.get_content_type()
                charset = part.get_content_charset()
                print("Content_Type: {0} Charset: {1}".format(content_type, charset))

                if content_type == 'text/plain':
                    self.mail_content['plain'] = part.get_payload(decode=True).decode(charset)
                elif content_type == 'text/html':
                    self.mail_content['html']  = part.get_payload(decode=True).decode(charset)
            
            else:
                self.mail_content['plain'] = message.get_payload(decode=True).decode(charset)

        return self.mail_content['plain'].strip() if self.mail_content['plain'] else self.mail_content['html'].strip()

    def download_attachment(self, message):
        for part in message.walk():
            if part.get_content_maintype() == 'multipart':
                continue
            if part.get('Content-Disposition') is None:
                continue

            filename = part.get_filename()
            filename = self.decode_content(filename)
            # print('FileName: ', filename)

            if not filename:
                continue
            
            # save attachment             
            with open(filename, 'wb') as attach:
                data = part.get_payload(decode=True) 
                attach.write(data)  
                print("attachment {0} saved".format(filename))

if __name__ == '__main__':

    host = 'pop.qq.com'  
    username = 'email '  
    password = 'password' 

    title = 'first demo'
    checker = Email_Checker(username, password, host)
    checker.filter_mails(title)

    lastest_msg = checker.mail_messages[-1]
    checker.download_attachment(lastest_msg)

最佳答案

查看完整内容

我用 imaplib 实现了下载最新标题的功能,只是我无法在QQ邮箱测试,你试试运行对不对
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-26 14:43:29 | 显示全部楼层    本楼为最佳答案   
本帖最后由 XiaoPaiShen 于 2019-11-28 03:28 编辑

我用 imaplib 实现了下载最新标题的功能,只是我无法在QQ邮箱测试,你试试运行对不对
import imaplib
import email

from email.header import decode_header

class Email_Checker:
    def __init__(self, email='', password='', server='imap.gmail.com'):
        self.server = server
        self.email = email
        self.password = password

        self.mail = imaplib.IMAP4_SSL(self.server)
        self.mail.login(self.email, self.password)
        self.mail.select('inbox')

        self.mail_content = {'plain': None, 'html': None}
        self.mail_messages = list()

    def decode_content(self, content):
        if not content:
            return None

        value, charset = decode_header(content)[0]
        if charset:
            value = value.decode(charset)
        return value    

    def filter_mails(self, title):
        status, data = self.mail.uid('search', None, "ALL")
        email_uids = data[0].split()
        for uid in email_uids:
            status, content = self.mail.uid('fetch', uid, '(RFC822)')
            raw_email = content[0][1]
            message = email.message_from_bytes(raw_email)
            mail_subject = message['subject']

            if mail_subject == title:
                self.mail_messages.append(message)

    def get_content(self, message):
        for part in message.walk():
            if part.is_multipart:
                content_type = part.get_content_type()
                charset = part.get_content_charset()
                print("Content_Type: {0} Charset: {1}".format(content_type, charset))

                if content_type == 'text/plain':
                    self.mail_content['plain'] = part.get_payload(decode=True).decode(charset)
                elif content_type == 'text/html':
                    self.mail_content['html']  = part.get_payload(decode=True).decode(charset)
            
            else:
                self.mail_content['plain'] = message.get_payload(decode=True).decode(charset)

        return self.mail_content['plain'].strip() if self.mail_content['plain'] else self.mail_content['html'].strip()

    def download_attachment(self, message):
        for part in message.walk():
            if part.get_content_maintype() == 'multipart':
                continue
            if part.get('Content-Disposition') is None:
                continue

            filename = part.get_filename()
            filename = self.decode_content(filename)
            # print('FileName: ', filename)

            if not filename:
                continue
            
            # save attachment             
            with open(filename, 'wb') as attach:
                data = part.get_payload(decode=True) 
                attach.write(data)  
                print("attachment {0} saved".format(filename))

if __name__ == '__main__':

    host = 'pop.qq.com'  
    username = 'email '  
    password = 'password' 

    title = 'first demo'
    checker = Email_Checker(username, password, host)
    checker.filter_mails(title)

    lastest_msg = checker.mail_messages[-1]
    checker.download_attachment(lastest_msg)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-27 04:54:06 | 显示全部楼层
我没有QQ邮箱,使用gmail测试,只能是下载新的邮件,如果下载过了,再运行程序,就不会再下载了。
也就是只检测一次,检测过了就不会再检测了。
QQ邮箱是这样的吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-11-27 23:16:46 | 显示全部楼层
XiaoPaiShen 发表于 2019-11-27 04:54
我没有QQ邮箱,使用gmail测试,只能是下载新的邮件,如果下载过了,再运行程序,就不会再下载了。
也就是 ...

QQ邮箱是如果subject同名,会把所有的同名的附件都下载下来。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-11-28 02:37:56 | 显示全部楼层
XiaoPaiShen 发表于 2019-11-28 02:06
我用 imaplib 实现了下载最新标题的功能,只是我无法在QQ邮箱测试,你试试运行对不对

卧槽!老哥牛逼!!!!!!!
然后能不能给这段代码写个备注呀,我也想学一学
顺便价格好友呗,说不定以后多多请教老哥
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-28 02:45:54 | 显示全部楼层
shenshuai 发表于 2019-11-28 02:37
卧槽!老哥牛逼!!!!!!!
然后能不能给这段代码写个备注呀,我也想学一学
顺便价格好友呗,说不定 ...

你先读读这段代码,有哪个地方不明白,我再给你解释
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-11-28 02:48:49 | 显示全部楼层
XiaoPaiShen 发表于 2019-11-28 02:45
你先读读这段代码,有哪个地方不明白,我再给你解释

不瞒老哥,这段代码我是真的看不懂,要不然我也不会去网上抄了。
我想学email模块,但是网上讲的都不好。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-28 07:31:59 | 显示全部楼层
shenshuai 发表于 2019-11-28 02:48
不瞒老哥,这段代码我是真的看不懂,要不然我也不会去网上抄了。
我想学email模块,但是网上 ...


初始化函数我做了一点修改,server应该可以从外面传进去。
你再重新考一下吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-9 13:06:32 | 显示全部楼层
朋友,这个怎么用win32com实现啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-16 13:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表