Python 用POP接收邮件
一、简介
POP(Post Office Protocal)最长用的POP版本是POP3,因此本文是以POP3为主。POP3非常简单,可以用来从邮件服务器上下载邮件,然后删除这些邮件。功能非常有限,后面讲解的IMAP完胜它,不过作为入门级的,还是有必要介绍一下,也对学习SMTP有帮助。
Python提供了poplib模块,它提供了使用POP的便利接口。
二、实例
由于pop3功能较IMAP非常有限,而且我最后的程序并没有使用pop3,所以,不详细讲解,下面通过一个例子来说明下较为常见的功能。
这个例子的功能为进入邮箱,查看所有的邮件。首先显示邮件的发件人、主题,查看邮箱主题内容。
1. 需要模块
import email, poplib, sys
2. 连接POP3服务器,登录个人邮箱账户
poplib提供POP3()方法和POP3_SSL()方法连接POP3服务器,区别和SMTP一样。gmail仍然使用POP3_SSL()方式,并返回class POP3实例
p = poplib.POP3_SSL('pop.gmail.com')
使用POP3.user(), POP3.pass_()方法来登录个人账户
try:
p.user(user)
p.pass_(passwd)
except poplib.error_proto: #可能出现的异常
print('login failed')
3. 现在已经进入个人账户,下一步,利用POP3.list()函数查看邮箱内邮件信息。
关于list()函数的详细说明,请点击这里。
list()函数有三个返回值,分别是:response, listings, octets
- response 应答信息,我测试中出现的结果:

2GQ38.jpg)
以b开头的字符串是Byte类型,我在实际测试的时候,返回的信息几乎都是Byte类型的。关于此类型及和普通字符串的转化会在后面举例说明。
- listings 是形如['message_id message_size',...]若干各message-id和message_size构成的list。后面就是通过message_id来检索邮件。我测试中出现的结果:

- octets 不是特别清楚啥意思。
response, listings, octets = p.list()
4. 最重要的就是listings数据
如上面解释的,listings是个list类型的数据,接下来我们取出listings中的message_id,也就是上面的 "1" "2" "3" "4" ...
for listing in listings: #每次需要一个listing
number, size = listing.split() #由于number和size是以空格分隔,所以利用split()函数分开,split()默认以' '为分隔
现在我们就取出了我们需要的message_id,也就是number,注意number需要从Byte类型转化为字符串类型。
5. POP3.top()函数
利用此函数,取出邮件的headers,如下:
response, lines, octets = p.top(number , 0)
lines存储内容,下面先转化成Message类型(lines默认为标准字符串类型,仅供说明,以实际代码为准)
message = email.message_from_string('\n'.join(lines))
6. 已经生成Message类,可以利用头部信息来查看From, Subject等信息
for header in 'From', 'To', 'Subject', 'Date':
if header in message:
print(header + ':' , message[header])
注意,此时的message[header]可能不会输出我们想看到的内容,有可能出现格式错乱问题,比如中英文的转化,所以还需要特殊来处理。处理方式请继续往下看IMAP部分。
7. 取出邮件所有信息
上面的top()函数只取出header信息以及根据参数确定的n行内容,如果用户希望查看邮件所有内容,那利用POP3.retr()函数取出
response, lines, octets = p.retr(number)
还是将lines中的内容转换成Message类型:
message = email.message_from_string('\n'.join(lines))
8. 已经有了邮件所有信息,可以通过Message.get_payload()取出邮件正文了。
但是,get_payload()函数并不一定返回邮件正文。以下是官方说明:
Return the current payload, which will be a list of Message objects when is_multipart() is True, or a string when is_multipart() is False.
在实际测试中,返回的就是a list of Message objects,这个问题困扰我很长时间,最终还是解决了,通过以下方法:
maintype = message.get_content_maintype()
if maintype == 'multipart':
for part in message.get_payload():
if part.get_content_maintype() == 'text':
mail_content = part.get_payload(decode=True).strip()
elif maintype == 'text':
mail_content = e.get_payload(decode=True).strip()
9. 此时,mail_content就是邮件正文了.
当然,如果是中文的话,这件事仍未完,还需要将它转化未'gbk',利用如下方式:
mail_content = mail_content.decode('gbk')
10. 到现在,基本已经大功告成了,能够取出邮箱中所有的邮件,并查看邮件的header内容和邮件正文了^_^
三、完整代码:
#-*- encoding:utf-8 -*-
#-*- encoding:gbk -*- import email, getpass, poplib, sys hostname = 'pop.gmail.com'
user = 'myUserName@gmail.com'
passwd = '***' p = poplib.POP3_SSL('pop.gmail.com') #与SMTP一样,登录gmail需要使用POP3_SSL() 方法,返回class POP3实例
try:
# 使用POP3.user(), POP3.pass_()方法来登录个人账户
p.user(user)
p.pass_(passwd)
except poplib.error_proto: #可能出现的异常
print('login failed')
else:
response, listings, octets = p.list()
for listing in listings:
number, size = listing.split() #取出message-id
number = bytes.decode(number)
size = bytes.decode(size)
print('Message', number, '( size is ', size, 'bytes)')
print()
response, lines, octets = p.top(number , 0)
# 继续把Byte类型转化成普通字符串
for i in range(0, len(lines)):
lines[i] = bytes.decode(lines[i])
#利用email库函数转化成Message类型邮件
message = email.message_from_string('\n'.join(lines))
# 输出From, To, Subject, Date头部及其信息
for header in 'From', 'To', 'Subject', 'Date':
if header in message:
print(header + ':' , message[header])
#与用户交互是否想查看邮件内容
print('Read this message [ny]')
answer = input()
if answer.lower().startswith('y'):
response, lines, octets = p.retr(number) #检索message并返回
for i in range(0, len(lines)):
lines[i] = bytes.decode(lines[i])
message = email.message_from_string('\n'.join(lines))
print('-' * 72)
maintype = message.get_content_maintype()
if maintype == 'multipart':
for part in message.get_payload():
if part.get_content_maintype() == 'text':
mail_content = part.get_payload(decode=True).strip()
elif maintype == 'text':
mail_content = e.get_payload(decode=True).strip()
try:
mail_content = mail_content.decode('gbk')
except UnicodeDecodeError:
print('Decoding to gbk error')
sys.exit(1)
print(mail_content)
print()
print('Delete this message? [ny]')
answer = input()
if answer.lower().startswith('y'):
p.dele(number)
print('Deleted')
finally:
print('log out')
p.quit()
Python 用POP接收邮件的更多相关文章
- 使用python发送和接收邮件
关于电子邮件 大学之前,基本不用邮箱,所以基本感觉不到它的存在,也不知道有什么用:然而大学之后,随着认识的人越来越多,知识越来越广泛,邮箱已然成为很重要的通讯工具,大学一些课程作业需要有邮箱发给老师, ...
- python3 - pop 接收邮件/ smtp 发送邮件
以下通过python3 实现接收和发送邮件,网上相关说明文档很多.请自己查阅,这里只写入代码, # 实例:通过poplib 模块接收指定账号的邮件并进行解码处理,结果可视化. #!/opt/pytho ...
- Python 用IMAP接收邮件
一.简介IMAP(Internet Message Access Protocol),这个协议与POP一样,也是从邮件服务器上下载邮件到本机,不过IMAP比POP的功能要更加强大些,IMAP除支持PO ...
- python 利用pop3接收邮件并保存附件
def SaveAttach():# login the pop3 server ,retrive the new mails ,and download the attachments dstdir ...
- python 利用imap接收邮件,并保存附件
def SaveAttachImap():# login the imap server ,retrive the new mails ,and download the attachments. ...
- Python中使用SMTP发送邮件以及POP收取邮件
假设我们自己的电子邮件地址是from@163.com,对方的电子邮件地址是to@sina.com(这里的地址虚拟的),现在我们用Outlook或者Foxmail之类的软件写好邮件,填上对方的Email ...
- Python接收邮件并保存至MySQL
转自:http://www.360doc.com/content/14/0103/13/11789990_342303735.shtml 参考了一些网络上的资料,做了个简单程序,使用python接收邮 ...
- python接收邮件
# -*- coding: utf-8 -*- import poplib import email from email.parser import Parser from email.header ...
- JavaMail入门第四篇 接收邮件
上一篇JavaMail入门第三篇 发送邮件中,我们学会了如何用JavaMail API提供的Transport类发送邮件,同样,JavaMail API中也提供了一些专门的类来对邮件的接收进行相关的操 ...
随机推荐
- hdu 4915 Parenthese sequence--2014 Multi-University Training Contest 5
主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4915 Parenthese sequence Time Limit: 2000/1000 MS (Ja ...
- 使用PHP顶替JS有趣DOM
較简单,我须要把一个导航页的数据整理好写入数据库.一个比較直观的方法是对html文件进行分析.通用的方法是用php的正則表達式来匹配.可是这样做开发和维护都非常困难,代码可读性非常差. 导航页的数据都 ...
- Java得到的一周的最后一天的一段时间内
Java得到的一周的最后一天的一段时间内 1.设计源代码 LastDayOfWeek.java: /** * @Title:LastDayOfWeek.java * @Package:com.you. ...
- Floodlight Controller 路线原则
SDN的出现能够使得各种复杂的路由协议从原本的Device OS中剥离出来,放在SDN Controller中.Controller用一种简单的协议来和全部的Router进行通信.就能够获得 ...
- jquery插件之DataTables 参数介绍
DataTables(http://www.datatables.net/)应该是我到目前为止见过的,功能最强大的表格解决方案(当然,不计算其它整套框架中的table控件在内). 先把它主页上写的特性 ...
- keil程序在外部RAM中调试的问题总结(个人的一点经验总结)
keil程序在内部RAM调试的基本步骤网上已经有非常多了,我就不再赘述,大家能够在网上搜到非常多. 可是有些时候内部RAM并不够用,这就须要将程序装入外部RAM中调试,而在这个过程中可能会出现各种各样 ...
- MongoDB详解学习历程
MongoDB是一个基于分布式文件存储的数据库,它是介于关系数据库和非关系数据库之间的产品. MongoDB支持的数据结构非常松散,类似json的bjson格式,因此可以存储比较复杂的数据类型.Mon ...
- timesten备份和恢复
ttIsql "DSN=ttwind;UID=cacheuser;PWD=cacheuser;OraclePWD=cacheuser;" --1.查看当前版本号 Command&g ...
- [CLR via C#]7. 常量和字段
原文:[CLR via C#]7. 常量和字段 7.1 常量 常量(constant)是一个特殊的值,它是一个从不变化的值. 在定义常量时,它的值必须在编译时确定.确定之后,编译器将常量的值保存到程序 ...
- POJ 3067 Japan 树状数组求逆序对
题目大意:有两排城市,这两排城市之间有一些路相互连接着,求有多少条路相互交叉. 思路:把全部的路先依照x值从小到大排序,x值同样的依照y值从小到大排序,然后插入边的时候,先找有多少比自己y值小的,这些 ...