一、前言


对于编程来说,我期望的是并不仅仅用于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_) 
  • 1
  • 2
  • 3
  • 4
使用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()
  • 1
  • 2
  • 3

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]
  • 1
  • 2

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

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

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

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

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

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

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

遍历一下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
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134

四、后续问题

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

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

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

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

pop.live.com是微软的

宁波整容医院http://www.lyxcl.org/

python想要保存QQ邮箱富途的附件相关推荐

  1. 【Python融于生活】之我想要保存QQ邮箱富途的附件

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

  2. python自动登录qq邮箱_selenium+python实现自动登陆QQ邮箱并发送邮件功能

    本期做一个selenium详细实例,会把我在元素定位中遇到的一些阻塞和经验分享给大家. (浏览器为Chrome) (如果只需要最终的完整代码,请直接跳转到文章最后) 浏览器打开QQ邮箱登录网址 fro ...

  3. python基础编程:selenium+python实现自动登陆QQ邮箱并发送邮件功能

    本期做一个selenium详细实例,会把我在元素定位中遇到的一些阻塞和经验分享给大家. (浏览器为Chrome) (如果只需要最终的完整代码,请直接跳转到文章最后) 浏览器打开QQ邮箱登录网址 QQ邮 ...

  4. selenium+python实现自动登陆QQ邮箱,并发送邮件

    这里写自定义目录标题 selenium+pycharm实战,登录QQ邮箱,并发送邮件 浏览器打开QQ邮箱登录网址 元素定位,输入QQ账号和QQ密码 元素定位,写信界面 元素定位,邮件发送 元素定位总结 ...

  5. python实现自动登录qq邮箱,写邮件并发送

    1 编程语言 python 3.5 2 需要安装xlrd库,用来打开Excel文件 3 在命令行中输入 python send.py [接收者邮件地址]   如:python send.py 1234 ...

  6. python实现自动登录QQ邮箱

    python 和selenium实现自动登录QQ邮箱 selenium需要先导入,pip install selenium 或者在pycharm里面点击file–settings–Project–Pr ...

  7. python+selenium自动登录QQ邮箱

    环境:win10x64+python3.5+chrome+chromedriver 需要安装的模块: 1.chromedriver 下载地址,下载后加入系统环境变量即可. 2.selenium # p ...

  8. python利用selenium登陆qq邮箱

    最开始自己写的代码: from selenium import webdriver browser=webdriver.Firefox() browser.get('https://mail.qq.c ...

  9. python实现模拟浏览器登录入口_登录采集——模拟浏览器登录QQ邮箱

    网络爬虫学习中,简单的静态页面数据,难以满足我们的一颗"好学"之心,且现在我们"好奇"的数据往往藏得很深,要么需要登录,要么为动态加载--今天,就来分享一下模拟 ...

最新文章

  1. OSPF有五种报文,hello,dd,lsr,lsu,lsack
  2. 【mysql】Mac下安装mysql5.7 完整步骤,大坑已解决
  3. sql over的作用及用法
  4. java condition_(原创)Java的ReentrantLock(可重入锁)下的Condition
  5. Excel2010中VLOOKUP函数跨工作簿使用实例:
  6. Android CardView卡片布局 标签: 控件
  7. css 横线_atom.css正式发布,从此跟CSS框架说拜拜。
  8. 博文视点 OpenParty第11期:世界黑客大会那些事
  9. 求两个已排序单链表中相同的数据(C语言)
  10. Windows上搭建SFTP服务器
  11. 数据库之SQL行列转换
  12. 微信小程序获取用户信息(附代码、流程图)
  13. 金融随机分析——二叉树资产定价模型 第一卷
  14. 蓝牙标准协议免费下载
  15. 两台虚拟服务器如何串联,两台tp-link路由器串联设置教程 | 192路由网
  16. 批量修改文件名,图文教学,2分钟简单学会
  17. 漫画:如何给女朋友解释灭霸的指响并不是真随机消灭半数宇宙人口的?
  18. 写作三件套(VScode Miktex Latex Workshop)入门三大坑
  19. 小练习使用html 中table表格 实现个人简历
  20. html代码 小球上下波动,HTML5CSS3特效-上下跳动的小球-遁地龙卷风

热门文章

  1. Linux 指令:怎样从文件中找到重复行?
  2. 线性判别函数:感知器、松弛算法、Ho-Kashyap算法
  3. 一、电脑端实现单片机与ESP8266的通信
  4. Unity-网络开发(三)
  5. 素描教程石膏像明暗素描技法
  6. 用C#打开Windows自带的图片传真查看器
  7. 水表自动抄表系统有什么功能
  8. IB 化学考纲巨变 ,全面分析新旧考纲区别
  9. 小学生智力测试软件,测试小学生智力的问题及答案
  10. 武汉某GIS企业机试题