一、前言


对于编程来说,我期望的是并不仅仅用于make money,而是出于生活,融于生活。
最近炒股,每天都会有一封邮件发到我的QQ邮箱,里面有今天账户的结算信息,感觉这个挺有意义的,可以记录每天的交易情况和相关费用,但是我又不想每天去下载这个附件。于是乎花了一个晚上研究了一下python的poplib库,完成了一个拉取QQ邮箱附件的程序。

二、实现

2.1 poplib是什么?

poplib是一个python的一个模块,用于专门的处理邮箱的邮件,是基于pop3的协议。
使用的话用import poplib就可以了。

2.2 代码说明

想要解析邮件分为几个步骤:

  • 第一步:创建链接
        pop_conn = poplib.POP3_SSL(self.host)  pop_conn.set_debuglevel(self.debugMode) pop_conn.user(self.user)  pop_conn.pass_(self.pass_) 
使用poplib库创建一个SSL的链接,然后分别设置这个connect的几个参数,分别是:- debugmode:0为关闭,1为开启。如果开启的话,会显示交互时的日志。
- username :邮箱的账号
- password :邮箱的密码
- host : 对应的邮箱的pop3协议的host,qq邮箱是pop.qq.com

注:这里有个坑爹的东西,如果直接用qq密码用作password的话,会提示这个报错 poplib.error_proto: -ERR Please using authorized code to login.

跟着这个链接进去看,是因为qq出于安全的考虑,使用pop协议的时候,需要使用一个16位的密保来进行操作。按照链接里面的提示设置好了密码,再填入就可以使用了。

  • 第二步:获取邮件

几个主要的API:

pop_conn.stat()
pop_conn.list()
pop_conn.retr()

stat()用于获取邮件的状态,例如:有46封邮件
Messages: 46. Size: 3819672

list()用于获取邮件的列表状态:
(‘+OK’, [‘1 196394’, ‘2 35328’, ‘3 195761’, ‘4 19024’, ‘5 63952’, ‘6 196662’, ‘7 45720’, ‘8 197030’, ‘9 15565’, ‘10 36985’, ‘11 2550’, ‘12 31237’, ‘13 26712’, ‘14 18984’, ‘15 15990’, ‘16 12196’, ‘17 21966’, ‘18 194291’, ‘19 194885’, ‘20 126483’, ‘21 14534’, ‘22 29710’, ‘23 196006’, ‘24 13974’, ‘25 34424’, ‘26 195320’, ‘27 202168’, ‘28 24900’, ‘29 22061’, ‘30 7843’, ‘31 53405’, ‘32 7958’, ‘33 7913’, ‘34 200682’, ‘35 5349’, ‘36 15979’, ‘37 34286’, ‘38 53619’, ‘39 198150’, ‘40 25144’, ‘41 7366’, ‘42 196818’, ‘43 214880’, ‘44 196847’, ‘45 18007’, ‘46 194614’], 461)

pop_conn.retr()则是用于获取每封邮件的状态了

  • 第三步:解析邮件

分为两步:
1、先把pop_conn.retr()获得的一封邮件格式化一下,把其中的分割符化成”\n”(具体这一步的意义我没有深究,应该是方便email模块去解析)

        messages = ["\n".join(mssg[1]) for mssg in messages]

注意每个邮件mssg里面只有mssg[1]是内容。

2、然后对邮件进行解析转化成Message对象

        messages = [Parser().parsestr(mssg) for mssg in messages]

3、然后就可以获取到对应的邮件内容了

直接获取了
主题:msg.get('subject')
时间:msg.get('Date')
发件人:email.utils.parseaddr(msg.get('from'))[1]
收件人:email.utils.parseaddr(msg.get('to'))[1]

不过这些我都不需要,我只需要里面的附件内容。

4、保存附件

        for part in msg.walk():fileName = part.get_filename()  # 保存附件if fileName:  fname = self.decode_str(fileName)fEx = open("%s%s"%(self.savePath,fname), 'wb')data = part.get_payload(decode=True)  fEx.write(data)  fEx.close()

遍历一下msg,如果有附件就存下来,这里需要注意的是需要对文件的名字进行解码。
然后找个目录存下来吧。

有个问题,不知道为什么只能取到最近的一个月的邮件,有点奇怪,不知道是不是QQ邮箱的限制了。

三、源码

#!/usr/bin/python
#-*- encoding: utf-8 -*-
# @auth atany 347702498@qq.com
# blog : http://blog.csdn.net/yang8456211import poplib
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import email
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8') # 默认的编码是ASCII..class MailManager:# 测试的邮件数量 0为所有testLimitMailCount  = 0def __init__(self, host, username, password, savePath, debugMode = 0):self.host = hostself.user = usernameself.pass_ = passwordself.debugMode = debugModeself.savePath = savePathdef _download_mail(self):print "...\n============ Begin to DownLoad ============"pop_conn = poplib.POP3_SSL(self.host)  pop_conn.set_debuglevel(self.debugMode) pop_conn.user(self.user)  pop_conn.pass_(self.pass_) print('Messages: %s. Size: %s' % pop_conn.stat())## 格式('+OK', ['1 12515', '2 196394', '3 35328', '4 195761', '5 19024'], 471)print pop_conn.list()messages = []for i in range(1, len(pop_conn.list()[1]) + 1):#print pop_conn.retr(i)messages.append(pop_conn.retr(i))# 太多了不好测试,限制一下if 0 != self.testLimitMailCount and i >= self.testLimitMailCount:break# mssg[1]为内容正文,加个回车换行把逗号分隔符,链接成一个完整字符串messages = ["\n".join(mssg[1]) for mssg in messages]  # 转化为邮件实例的Message对象messages = [Parser().parsestr(mssg) for mssg in messages]  #print messagesfor i in range(0, len(messages)):msg = messages[i]self._save_email(msg ,i)def _save_email(self, msg, index):# 其他的可能用到的属性mailName = "Mail[%d]-%s.log - %s" % (index, self.decode_str(msg.get('subject')),msg["Date"])  print mailName# mailName = "Mail[%d].log" % (index)  # print mailName# print os.getcwd()# file_ = open(mailName, 'w')# print >> file_, "Date: ", msg["Date"]  # print >> file_, "From: ", email.utils.parseaddr(msg.get('from'))[1]  # print >> file_, "To: ", email.utils.parseaddr(msg.get('to'))[1]  # print >> file_, "Subject: ", self.decode_str(msg.get('subject'))  #主题 =?gbk?B?zfjJz7m6xrHPtc2zLdPDu6fWp7i2zajWqg==?=# print >> file_, "Data: "# 我只想要富途的附件From = email.utils.parseaddr(msg.get('from'))[1]if "@futu5.com" not in From:returnfor part in msg.walk():fileName = part.get_filename()  # contentType = part.get_content_type()# mycode=part.get_content_charset()# 保存附件if fileName:  fname = self.decode_str(fileName)fEx = open("%s%s"%(self.savePath,fname), 'wb')data = part.get_payload(decode=True)  fEx.write(data)  fEx.close()#file_.close()  def decode_str(self, s):# # 下面的三行代码只是为了解码# h = email.Header.Header(subject)# # dh:内容+编码[('\xcd\xf8\xc9\xcf\xb9\xba\xc6\xb1\xcf\xb5\xcd\xb3-\xd3\xc3\xbb\xa7\xd6\xa7\xb8\xb6\xcd\xa8\xd6\xaa', 'gbk')]# dh = email.Header.decode_header(h)# if None != dh[0][1] and None != dh[0][0]:#     subject = unicode(dh[0][0], dh[0][1]).encode('utf8')value, charset = decode_header(s)[0]if charset:value = value.decode(charset)return valuedef _display_email(self, msg):passdef _display_info(self):print "============ DisplayInfo Begin ============"print "username : " , self.userprint "password : " , self.pass_print "host : " , self.hostprint "============ DisplayInfo End ============"if __name__ == '__main__':host = 'pop.qq.com'  username = ''# QQ邮箱这里改成16位的密保了,这里有个问题,一旦修改了密码或者独立密码,需要重新去生成一下密保# 这里输入自己的密保就可以了password = ''# 不传debugMode 就是默认为0,不显示服务器日志debugMode = 0#保存附件的位置savePath = "/Users/yangguang/Documents/stock/"mailManager = MailManager(host, username, password, savePath, debugMode)mailManager._display_info()mailManager._download_mail()

四、后续问题

1)可以是用定时任务做个每天定时拉取应该不错。
2)关于文章中的一些转码问题还是头疼了一小会,没想到系统的defaultencoding是ASCII.. 所以要在文件头加上

import sys
reload(sys)
sys.setdefaultencoding('utf-8') # 默认的编码是ASCII..

关于解码:
使用这个解码方法解出dh也是可以的,dh[0][0]是内容,dh [0][1]是当前的编码。

3)关于各个邮箱的pop协议的host可以自行百度
例如:
pop.163.com是网易的
pop.live.com是微软的

五、写在最后

既然选择,那么热爱

杨光(atany)原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。
博文地址:http://blog.csdn.net/yang8456211/article/details/78449710
博客地址:http://blog.csdn.net/yang8456211
本文遵循“署名-非商业用途-保持一致”创作公用协议

【Python融于生活】之我想要保存QQ邮箱富途的附件相关推荐

  1. python想要保存QQ邮箱富途的附件

    一.前言 对于编程来说,我期望的是并不仅仅用于make money,而是出于生活,融于生活.  最近炒股,每天都会有一封邮件发到我的QQ邮箱,里面有今天账户的结算信息,感觉这个挺有意义的,可以记录每天 ...

  2. Python爬取糗事百科段子+定时发送QQ邮箱

    文章目录 前言 1. 库导入及介绍 2. 获取网页源码 3. 提取需要的信息 4. 优化输出数据 5. 发送邮件 6. 实现定时发送 7. 源码 前言 学习Python爬虫也有段时间了,总想着搞点事做 ...

  3. Python邮件发送SMATP模块详细总结(含qq邮箱及163邮箱服务开启及授权码获取,多附件发送)

    Python实现电子邮件发送 在生活中或许我们多数都在用微信或者是QQ,但是工作中就会涉及邮件了,我也是最近在工作中用到了,所以找了些资料,有的较为完备有的就特别零散,所以自己也来整理分享一下.这里主 ...

  4. python 发送邮件connect none_Python发送邮件功能示例【使用QQ邮箱】

    本文实例讲述了Python发送邮件功能.分享给大家供大家参考,具体如下: 这里以QQ邮箱为例说明 登录邮箱点账号 开启smtp 开启时会要求你发送一条短信,发送完成后点已发送. 就有授权码了 代码如下 ...

  5. python凯撒密码详解_四十八、Python用smtp发邮件详解(163和QQ邮箱)

    Python发邮件详解 一.利用163的smtp发送邮件 import smtplibfrom email.mime.text import MIMETextfrom email.header imp ...

  6. python向自己qq邮箱发信息_【奇巧淫技】python!每天早上八点自动发送天气预报邮件到QQ邮箱...

    本文为CSDN博主「SunriseCai」的原创文章 补充 有不少读者留言说本文章没有用,因为天气预报直接打开手机就可以收到了,为何要多此一举发送到邮箱呢!!!那我在这里只能说:因为你没用,所以你没用 ...

  7. python发邮件主机找不到_Python 使用QQ邮箱发邮件

    QQ邮箱太恶心了.经常改验证方式 阿福最近的脚本不能用了,研究了一上午. 终于研究出来了. def sendmail(data): content = data['content'] msg = MI ...

  8. [python应用案例] 一.BeautifulSoup爬取天气信息并发送至QQ邮箱

    前面作者写了很多Python系列文章,包括: Python基础知识系列:Python基础知识学习与提升 Python网络爬虫系列:Python爬虫之Selenium+Phantomjs+CasperJ ...

  9. python能在生活中做什么-Python能在生活中做什么

    很多人学习Python就是为了在人工智能.大数据等领域谋求一份高薪工作,Python其实很接地气,我们如果学习了Python而不把它作为一种谋生手段也可以在生活中解决很多问题,那么Python能在生活 ...

最新文章

  1. 互联网协议 — New IP 网络架构
  2. Storage与cookie
  3. python经典好书-python经典书籍推荐
  4. KEIL-MDK 5 CMSIS的问题
  5. __cdecl、__stdcall、__fastcall 与 __pascal 浅析
  6. 《团队作业》五小福团队--UNO的博客链接汇总
  7. linux查看cpu、内存、版本信息
  8. 27. JavaScript Cookies
  9. 软件设计师-知识产权和标准化知识
  10. 【毕业设计】基于SSM图书信息管理系统
  11. RENIX 软件如何进行IP地址管理——网络测试仪实操
  12. 不是计算机网络教室功能的是,精选:谈计算机网络教室在教学中的应用原稿
  13. Netflix-Eureka服务注册与发现说明文档
  14. 武汉理工计算机保研去华科,武汉理工大学2021届保研率14.9%,主要保研本校、武大、华科...
  15. 不可不知的CPU风扇清理技巧
  16. Respon.WriteFile 下载文件
  17. 1812. 方形牧场
  18. Python学习笔记之eval函数简析
  19. vue-cli3.0 + echarts展示中国地图
  20. 运放的选取标准和规则

热门文章

  1. 使用apache服务部署静态网站--初篇
  2. 公益运动App平台开发详情
  3. 实战十三:基于BPR算法实现个性化排名推荐 代码+数据
  4. 模块化开发一个电子商务网站
  5. java if(true)_使用 if(true) 和 if(false)
  6. 播音主持如何运气发声?早上应该如何练声?
  7. unity接入微信支付完成切换前台游戏闪退
  8. 基于单片机控制的交通灯系统设计
  9. 全国地理信息相关单位名单汇总2010
  10. 脑电数据分析方法与应用实例简介-EEG Processing and Feature 1