一、简介
  POP(Post Office Protocal)最长用的POP版本是POP3,因此本文是以POP3为主。POP3非常简单,可以用来从邮件服务器上下载邮件,然后删除这些邮件。功能非常有限,后面讲解的IMAP完胜它,不过作为入门级的,还是有必要介绍一下,也对学习SMTP有帮助。
  Python提供了poplib模块,它提供了使用POP的便利接口。
二、实例
  由于pop3功能较IMAP非常有限,而且我最后的程序并没有使用pop3,所以,不详细讲解,下面通过一个例子来说明下较为常见的功能。
  这个例子的功能为进入邮箱,查看所有的邮件。首先显示邮件的发件人、主题,查看邮箱主题内容。
1. 需要模块

  1. import email, poplib, sys

2. 连接POP3服务器,登录个人邮箱账户
  poplib提供POP3()方法和POP3_SSL()方法连接POP3服务器,区别和SMTP一样。gmail仍然使用POP3_SSL()方式,并返回class POP3实例

  1. p = poplib.POP3_SSL('pop.gmail.com')

  使用POP3.user(), POP3.pass_()方法来登录个人账户

  1. try:
  2. p.user(user)
  3. p.pass_(passwd)
  4. except poplib.error_proto: #可能出现的异常
  5. print('login failed')

3. 现在已经进入个人账户,下一步,利用POP3.list()函数查看邮箱内邮件信息。

  关于list()函数的详细说明,请点击这里
list()函数有三个返回值,分别是:response, listings, octets

  • response 应答信息,我测试中出现的结果:

    

  以b开头的字符串是Byte类型,我在实际测试的时候,返回的信息几乎都是Byte类型的。关于此类型及和普通字符串的转化会在后面举例说明。

  • listings 是形如['message_id message_size',...]若干各message-id和message_size构成的list。后面就是通过message_id来检索邮件。我测试中出现的结果:

  

  • octets 不是特别清楚啥意思。
  1. response, listings, octets = p.list()

4. 最重要的就是listings数据

  如上面解释的,listings是个list类型的数据,接下来我们取出listings中的message_id,也就是上面的 "1" "2" "3" "4" ...

  1. for listing in listings: #每次需要一个listing
  2. number, size = listing.split() #由于number和size是以空格分隔,所以利用split()函数分开,split()默认以' '为分隔

  现在我们就取出了我们需要的message_id,也就是number,注意number需要从Byte类型转化为字符串类型。

5. POP3.top()函数

  利用此函数,取出邮件的headers,如下:

  1. response, lines, octets = p.top(number , 0)

  lines存储内容,下面先转化成Message类型(lines默认为标准字符串类型,仅供说明,以实际代码为准)

  1. message = email.message_from_string('\n'.join(lines))

6. 已经生成Message类,可以利用头部信息来查看From, Subject等信息

  1. for header in 'From', 'To', 'Subject', 'Date':
  2. if header in message:
  3. print(header + ':' , message[header])

  注意,此时的message[header]可能不会输出我们想看到的内容,有可能出现格式错乱问题,比如中英文的转化,所以还需要特殊来处理。处理方式请继续往下看IMAP部分。

7. 取出邮件所有信息
  上面的top()函数只取出header信息以及根据参数确定的n行内容,如果用户希望查看邮件所有内容,那利用POP3.retr()函数取出

  1. response, lines, octets = p.retr(number)

  还是将lines中的内容转换成Message类型:

  1. 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,这个问题困扰我很长时间,最终还是解决了,通过以下方法:

  1. maintype = message.get_content_maintype()
  2. if maintype == 'multipart':
  3. for part in message.get_payload():
  4. if part.get_content_maintype() == 'text':
  5. mail_content = part.get_payload(decode=True).strip()
  6. elif maintype == 'text':
  7. mail_content = e.get_payload(decode=True).strip()

9. 此时,mail_content就是邮件正文了.

  当然,如果是中文的话,这件事仍未完,还需要将它转化未'gbk',利用如下方式:

  1. mail_content = mail_content.decode('gbk')

10. 到现在,基本已经大功告成了,能够取出邮箱中所有的邮件,并查看邮件的header内容和邮件正文了^_^
三、完整代码:

  1. #-*- encoding:utf-8 -*-
  2. #-*- encoding:gbk -*-
  3.  
  4. import email, getpass, poplib, sys
  5.  
  6. hostname = 'pop.gmail.com'
  7. user = 'myUserName@gmail.com'
  8. passwd = '***'
  9.  
  10. p = poplib.POP3_SSL('pop.gmail.com') #与SMTP一样,登录gmail需要使用POP3_SSL() 方法,返回class POP3实例
  11. try:
  12. # 使用POP3.user(), POP3.pass_()方法来登录个人账户
  13. p.user(user)
  14. p.pass_(passwd)
  15. except poplib.error_proto: #可能出现的异常
  16. print('login failed')
  17. else:
  18. response, listings, octets = p.list()
  19. for listing in listings:
  20. number, size = listing.split() #取出message-id
  21. number = bytes.decode(number)
  22. size = bytes.decode(size)
  23. print('Message', number, '( size is ', size, 'bytes)')
  24. print()
  25. response, lines, octets = p.top(number , 0)
  26. # 继续把Byte类型转化成普通字符串
  27. for i in range(0, len(lines)):
  28. lines[i] = bytes.decode(lines[i])
  29. #利用email库函数转化成Message类型邮件
  30. message = email.message_from_string('\n'.join(lines))
  31. # 输出From, To, Subject, Date头部及其信息
  32. for header in 'From', 'To', 'Subject', 'Date':
  33. if header in message:
  34. print(header + ':' , message[header])
  35. #与用户交互是否想查看邮件内容
  36. print('Read this message [ny]')
  37. answer = input()
  38. if answer.lower().startswith('y'):
  39. response, lines, octets = p.retr(number) #检索message并返回
  40. for i in range(0, len(lines)):
  41. lines[i] = bytes.decode(lines[i])
  42. message = email.message_from_string('\n'.join(lines))
  43. print('-' * 72)
  44. maintype = message.get_content_maintype()
  45. if maintype == 'multipart':
  46. for part in message.get_payload():
  47. if part.get_content_maintype() == 'text':
  48. mail_content = part.get_payload(decode=True).strip()
  49. elif maintype == 'text':
  50. mail_content = e.get_payload(decode=True).strip()
  51. try:
  52. mail_content = mail_content.decode('gbk')
  53. except UnicodeDecodeError:
  54. print('Decoding to gbk error')
  55. sys.exit(1)
  56. print(mail_content)
  57. print()
  58. print('Delete this message? [ny]')
  59. answer = input()
  60. if answer.lower().startswith('y'):
  61. p.dele(number)
  62. print('Deleted')
  63. finally:
  64. print('log out')
  65. p.quit()

Python 用POP接收邮件的更多相关文章

  1. 使用python发送和接收邮件

    关于电子邮件 大学之前,基本不用邮箱,所以基本感觉不到它的存在,也不知道有什么用:然而大学之后,随着认识的人越来越多,知识越来越广泛,邮箱已然成为很重要的通讯工具,大学一些课程作业需要有邮箱发给老师, ...

  2. python3 - pop 接收邮件/ smtp 发送邮件

    以下通过python3 实现接收和发送邮件,网上相关说明文档很多.请自己查阅,这里只写入代码, # 实例:通过poplib 模块接收指定账号的邮件并进行解码处理,结果可视化. #!/opt/pytho ...

  3. Python 用IMAP接收邮件

    一.简介IMAP(Internet Message Access Protocol),这个协议与POP一样,也是从邮件服务器上下载邮件到本机,不过IMAP比POP的功能要更加强大些,IMAP除支持PO ...

  4. python 利用pop3接收邮件并保存附件

    def SaveAttach():# login the pop3 server ,retrive the new mails ,and download the attachments dstdir ...

  5. python 利用imap接收邮件,并保存附件

    def SaveAttachImap():# login the imap server ,retrive the  new mails ,and download the attachments. ...

  6. Python中使用SMTP发送邮件以及POP收取邮件

    假设我们自己的电子邮件地址是from@163.com,对方的电子邮件地址是to@sina.com(这里的地址虚拟的),现在我们用Outlook或者Foxmail之类的软件写好邮件,填上对方的Email ...

  7. Python接收邮件并保存至MySQL

    转自:http://www.360doc.com/content/14/0103/13/11789990_342303735.shtml 参考了一些网络上的资料,做了个简单程序,使用python接收邮 ...

  8. python接收邮件

    # -*- coding: utf-8 -*- import poplib import email from email.parser import Parser from email.header ...

  9. JavaMail入门第四篇 接收邮件

    上一篇JavaMail入门第三篇 发送邮件中,我们学会了如何用JavaMail API提供的Transport类发送邮件,同样,JavaMail API中也提供了一些专门的类来对邮件的接收进行相关的操 ...

随机推荐

  1. Tomcat剖析(四):Tomcat默认连接器(2)

    Tomcat剖析(四):Tomcat默认连接器(2) 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三): ...

  2. Android:仿手机QQ朋友动态ListView

    1.介绍: 使用此博客XListView模仿Android版本QQ朋友动态ListView效果.效果如下面的截图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  3. ajax——client访问webservice基本用法

    学前aps.net当我学会了使用服务器端的访问webservice方法,然后实现一个样本:web server模拟网上购物,今天学习asp.net ajax的时候学习到了client直接訪问webse ...

  4. FPGA笔记-阅读.dat文件

    阅读.dat图像文件 .dat文件是matlab生成的图像文件 initial begin // Initialize Inputs CLK = 0; RST = 1; IMAGE_DATA = 0; ...

  5. 利用WebBrowser彻底解决Web打印问题

    原文:利用WebBrowser彻底解决Web打印问题 利用WebBrowser彻底解决Web打印问题(包括后台打印) BS架构下的打印大家是怎么解决的呢,我最近作了一个项目正好负责这一块,不仅要求打印 ...

  6. 关于fork()函数的作用

    (1)    先看一个实例: #include <unistd.h>; #include <sys/types.h>; main () {           pid_t pi ...

  7. UVA - 11986 Save from Radiation

    Description J Save from Radiation Most of you are aware of Nuclear Power Plant Explosion at Fukushim ...

  8. MFC中的HOOK编程

    HOOK,n.钩, 吊钩,通常称钩子. 在计算机中,是Windows消息处理机制的一个平台,应用程序能够在上面设置子程以监视指定窗体的某种消息,并且所监视的窗体能够是其它进程所创建的.当消息到达后,在 ...

  9. Linq技术四:动态Linq技术 -- Linq.Expressions

    前面介绍了Linq的三个方面应用:Linq to SQL, Linq to XML和Linq to Object,这篇介绍一下动态Linq的实现方式及应用场景. 命名空间: System.Linq; ...

  10. 多线程学习之五超时模式Timer

    timed[超时模式]案例:一个线程提供下载数据,另一个线程执行下载,如果有5秒钟以上,提供下载的线程没有提供数据,下载线程因超时异常,停止下载线程运行. 超时异常类 /** * */ package ...