鱼C论坛

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

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

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

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

  8. def get_mails(prefix):
  9.     host = 'pop.qq.com'  
  10.     username = 'email '  
  11.     password = 'password'  
  12.       
  13.     server = poplib.POP3(host)
  14.     server.user(username)
  15.     server.pass_(password)
  16.     # 获得邮件
  17.     messages = [server.retr(i) for i in range(1, len(server.list()[1]) + 1)]  
  18.     messages = [b'\r\n'.join(mssg[1]).decode() for mssg in messages]  
  19.     messages = [Parser().parsestr(mssg) for mssg in messages]  
  20.     print("===="*10)
  21.     messages = messages[::-1]
  22.     for message in messages:  
  23.         subject = message.get('Subject')
  24.         subject = decode_str(subject)
  25.         #如果标题匹配
  26.         if subject and subject[:len(prefix)] == prefix:
  27.             value = message.get('From')
  28.             if value:
  29.                 hdr, addr = parseaddr(value)
  30.                 name = decode_str(hdr)
  31.                 value = u'%s <%s>' % (name, addr)
  32.             print("发件人: %s" % value)
  33.             print("标题:%s" % subject)
  34.             for part in message.walk():  
  35.                 fileName = part.get_filename()  
  36.                 fileName = decode_str(fileName)
  37.                 # 保存附件  
  38.                 if fileName:  
  39.                     with open(fileName, 'wb') as fEx:
  40.                         data = part.get_payload(decode=True)
  41.                         fEx.write(data)  
  42.                         print("附件%s已保存" % fileName)
  43.     server.quit()  

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

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

  1. import imaplib
  2. import email

  3. from email.header import decode_header

  4. class Email_Checker:
  5.     def __init__(self, email='', password='', server='imap.gmail.com'):
  6.         self.server = server
  7.         self.email = email
  8.         self.password = password

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

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

  14.     def decode_content(self, content):
  15.         if not content:
  16.             return None

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

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

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

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

  37.                 if content_type == 'text/plain':
  38.                     self.mail_content['plain'] = part.get_payload(decode=True).decode(charset)
  39.                 elif content_type == 'text/html':
  40.                     self.mail_content['html']  = part.get_payload(decode=True).decode(charset)
  41.             
  42.             else:
  43.                 self.mail_content['plain'] = message.get_payload(decode=True).decode(charset)

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

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

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

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

  62. if __name__ == '__main__':

  63.     host = 'pop.qq.com'  
  64.     username = 'email '  
  65.     password = 'password'

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

  69.     lastest_msg = checker.mail_messages[-1]
  70.     checker.download_attachment(lastest_msg)
复制代码

最佳答案

查看完整内容

我用 imaplib 实现了下载最新标题的功能,只是我无法在QQ邮箱测试,你试试运行对不对
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

  1. import imaplib
  2. import email

  3. from email.header import decode_header

  4. class Email_Checker:
  5.     def __init__(self, email='', password='', server='imap.gmail.com'):
  6.         self.server = server
  7.         self.email = email
  8.         self.password = password

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

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

  14.     def decode_content(self, content):
  15.         if not content:
  16.             return None

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

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

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

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

  37.                 if content_type == 'text/plain':
  38.                     self.mail_content['plain'] = part.get_payload(decode=True).decode(charset)
  39.                 elif content_type == 'text/html':
  40.                     self.mail_content['html']  = part.get_payload(decode=True).decode(charset)
  41.             
  42.             else:
  43.                 self.mail_content['plain'] = message.get_payload(decode=True).decode(charset)

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

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

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

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

  62. if __name__ == '__main__':

  63.     host = 'pop.qq.com'  
  64.     username = 'email '  
  65.     password = 'password'

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

  69.     lastest_msg = checker.mail_messages[-1]
  70.     checker.download_attachment(lastest_msg)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

QQ邮箱是如果subject同名,会把所有的同名的附件都下载下来。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

卧槽!老哥牛逼!!!!!!!
然后能不能给这段代码写个备注呀,我也想学一学
顺便价格好友呗,说不定以后多多请教老哥
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

你先读读这段代码,有哪个地方不明白,我再给你解释
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

不瞒老哥,这段代码我是真的看不懂,要不然我也不会去网上抄了。
我想学email模块,但是网上讲的都不好。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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


初始化函数我做了一点修改,server应该可以从外面传进去。
你再重新考一下吧。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-2-9 13:06:32 | 显示全部楼层
朋友,这个怎么用win32com实现啊
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-28 00:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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