python 接收邮件服务器地址_Python 用IMAP接收邮件

一、简介

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

多个邮件文件夹(收件箱、发件箱、垃圾邮件...)

IMAP服务器上进行标记如:Seen, Replied, Read, Deleted

在服务器端的文件夹之间拷贝和移动邮件

...

在IMAP的各版本中,最流行的是IMAP4。我们就使用IMAP4

由于,我需要搜索是否有未读邮件,也就是利用邮件服务器的Flag,所以IMAP是非常适合的,我的程序就利用的是IMAP。

在Python的标准库包含一个imaplib模块,可以利用这个模块。但是,这个模块的缺陷就是把大量解析的工作留给客户端程序员。

二、IMAPClient

IMAPClient是一个非常受欢迎的IMAPCLient包,这个模块不在标准Python库中。IMAPClient包是由一名叫做Menno Smits的Python程序员编写的。官网网址:http://imapclient.freshfoo.com/。可以在这里查看手册文档。这个包是基于标准库imaplib,不过要更强大。下面我们来介绍下怎样安装。

1. virtualenv

说实话,我本人对virtualenv的理解也不透彻,以字面上来理解为虚拟环境。可以把一些模块、包安装在特定的virtualenv里,一旦安装了virtualenv,你就创建任意多个自组织的虚拟python环境,在这个环境里,可以安装、下载包。

好吧,废话就不多说,直接说方法。

这里是virtualenv的详细说明,上面介绍了非常详细的安装方法,按照我自己的经验,可以简化为以下步骤:

$ [sudo] pip install virtualenv

$ [sudo] pip install https://github.com/pypa/virtualenv/tarball/develop

$ curl -O https://pypi.python.org/packages/source/v/virtualenv/ virtualenv-X.X.tar.gz

$ tar xvfz virtualenv-X.X.tar.gz

$ cd virtualenv-X.X

$ [sudo] python setup.py install

注意,上面下载的 virtualenv-X.X.tar.gz 中的X是型号,需要把它改成数字,详细版本类型可以参考:https://pypi.python.org/packages/source/v/virtualenv/

这样,virtualenv已经安装好。下面需要创建虚拟环境实例,步骤如下:

$ virtualenv --no-site-packages myenv

$ cd myenv

2. 安装IMAPClient

myenv 为自己定义的虚拟环境的名字。这样,我们已经在myenv里面,接下来就可一安装IMAPClient包了。步骤如下:

$ sudo pip install imapclient

$ python -c 'import imapclient'

此时,可以在python下使用imapclient模块,但是不能在python3下使用,在网上查了一些资料,尤其是看了上面的那个介绍virtualenv的网页,没找到有用的,但是,回头发现,这个imapclient是好使的了,不用进入gmapenv,直接使用即可,got it!

注意,上面用到了pip工具,如果没有的话一定要安装啊。

$ sudo apt-get install pip

三、开始正式学习IMAP1. 因为可能会出现中文,因此在程序的最上面,必须加上如下代码:

#-*- encoding: utf-8 -*-#-*- encoding: gbk -*-

2. 所需模块

importgetpass, email, sysfrom imapclient import IMAPClient

3. 连接服务、登录账户

这一步也没什么好讲的。代码如下:

#通过以下方式连接smtp服务器,没有考虑异常情况,详细请参考官方文档

c = IMAPClient(hostname = 'imap.gmail.com', ssl=True)try:

c.login(username, passwd)#登录个人帐号

exceptc.Error:print('Could not log in')

sys.exit(1)

4. 进入收件箱,查看未读邮件

c.select_folder('INBOX', readonly =True)

result= c.search('UNSEEN')

利用select_folder()函数进行文件夹,'INBOX'为收件箱,readonly = True 表明只读并不修改任何信息

利用search()函数选择想要的邮件,'UNSEEN'是邮件的flag,关于邮件的flag就不特别说明了,返回邮件的message-id

5. 有了未读邮件的ID(result),下面利用fetch()函数将邮件取来(下载到本机)

msgdict = c.fetch(result, ['BODY.PEEK[]'] )

通过fetch()函数取得邮件内容,fetch()的详细介绍请见这里

fetch(self, message, data) 其中self参数可忽略,message为message_id, data 的作用是抓取message中的哪些部分。  官方文档中没有给出data的其他可选的参数,我一开始怎么都不找到,最终在stackoverflow中进行提问,一位大哥把这个文档介绍给我,在 6.4.5 FETCH Command 。这里面非常详细的介绍了各个函数的各种细节,当然也可以查到data其他可选的参数 6.4.5 表示的是原书的节。特别感谢这位哥们,人类的力量是无穷的啊!

我们只需要'BODY.PEEK[]'即可。

6. 已经把邮件取出,下面开始解析邮件

for message_id, message inmsgdict.items():

e= email.message_from_string(message['BODY[]']) #生成Message类型

7. 得到的 e 即为Message类型的邮件,先面开始将又将中解析出'From', 'Subject'

还记得上面在POP讲解中,我们遇到的不能显示中文的问题吗?在IMAP中仍会出现,下面就讲解解决办法

由于'From', 'Subject' header有可能有中文,必须把它转化为中文,在这个点上,耽误了我很长时间,最终在网上查到了一个方法:http://blog.csdn.net/bonnshore/article/details/8729984 虽然不是很明白,但是能把问题解决就是王道。代码如下:

subject = email.header.make_header(email.header.decode_header(e['SUBJECT'])) #必须保证包含subject

mail_from = email.header.make_header(email.header.decode_header(e['From']))

8. 从Message e中解析出content正文

同上一篇的POP一样,根据get_payload()返回的不同类型,选择解析方法,代码如下:

maintype =e.get_content_maintype()if maintype == 'multipart':for part ine.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()#此时,需要把content转化成中文,利用如下方法:

try:

mail_content= mail_content.decode('gbk')exceptUnicodeDecodeError:print('decode error')

sys.exit(1)

9. 至此,我们已经完成了查看是否有未读邮件。如果有的话将未读邮件的'From', 'Subject', content解析出来。正如上面完成的 mail_from, subject, mail_content一样,现在可以完美的显示,即使有中文!

四、完整代码

#-*- encoding: utf-8 -*-#-*- encoding: gbk -*-

#因为可能会用到中文,所以必须有上面的这两句话

#引入模块及IMAPClient类

importgetpass, email, sysfrom imapclient importIMAPClient

hostname= 'imap.gmail.com' #gmail的smtp服务器网址

username = 'myUserName@gmail.com'passwd= '***'c= IMAPClient(hostname, ssl= True) #通过一下方式连接smtp服务器,没有考虑异常情况,详细请参考官方文档

try:

c.login(username, passwd)#登录个人帐号

exceptc.Error:print('Could not log in')

sys.exit(1)else:

c.select_folder('INBOX', readonly = True)

#利用select_folder()函数进行文件夹,'INBOX'为收件箱,readonly = True 表明只读并不修改任何信息

result = c.search('UNSEEN')

msgdict = c.fetch(result, ['BODY.PEEK[]'] )

#现在已经把邮件取出来了,下面开始解析邮件

for message_id, message inmsgdict.items():

e= email.message_from_string(message['BODY[]']) #生成Message类型#由于'From', 'Subject' header有可能有中文,必须把它转化为中文

subject = email.header.make_header(email.header.decode_header(e['SUBJECT']))

mail_from= email.header.make_header(email.header.decode_header(e['From']))#解析邮件正文

maintype =e.get_content_maintype()if maintype == 'multipart':for part ine.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()#此时,需要把content转化成中文,利用如下方法:

try:

mail_content= mail_content.decode('gbk')exceptUnicodeDecodeError:print('decode error')

sys.exit(1)else:print('new message')print('From:', mail_from)print('Subject:', subject)

getstr= input('if you wanna read it, input y:')if getstr.startswith('y'):print('-'*10, 'mail content', '-'*10)print(mail_content.replace('
', '\n'))print('-'*10, 'mail content', '-'*10)

finally:

c.logout()

五、总结

至此,我们已经学习了利用Python编写邮件服务的所有非常基本的内容,由于我的需求不是很高,目标不是做成一个功能强大的邮箱客户端,所以诸如:MIME、附件、图片等功能都没有学习,当然也没有介绍。

因为我们现在接收的邮件,大多数都是MIME格式的,不过上文的包含了点解析MIME格式邮件的代码。详细请参考《Foundations of Python3 Network Programming. 2nd Edition》Chaper E-mail Composition and Decoding。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338750.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

流媒体服务器 php,nginx 流媒体服务器 FFmpeg 截图

预备:yum install -y automake autoconf libtool gcc gcc-c1.安装phpyum -y install php-gd php-xml php-mbstring php-ldap php-pear php-xmlrpc php-devel php-fpm2.安装 nginxyum –y install nginx nginx-devel3.安装FFmpeg安装 Install ffmpeg 等模块yum -y install ffmpe…

C语言应用笔记:C语言typedef关键字及其使用

C 语言允许用户使用 typedef 关键字来定义自己习惯的数据类型名称,来替代系统默认的基本类型名称、数组类型名称、指针类型名称与用户自定义的结构型名称、共用型名称、枚举型名称等。一旦用户在程序中定义了自己的数据类型名称,就可以在该程序中用自己的…

java不支持发行版本12_主要发行版本后Java开发人员应使用的15种工具

java不支持发行版本12新部署的生存工具包:适用于Java开发人员的工具,这些工具经常将代码部署到生产中! Takipi会检测生产中的所有错误,并像发生错误时一样显示变量值 立即部署并获得免费的T恤 新部署的终极生存套件 与在僵尸末…

php get raw,file_get_contents(“php:// input”)或$ HTTP_RAW_POST

慕用2447696file_get_contents(php:// input) - 获取原始POST数据,你需要在编写API时使用它,并且需要XML / JSON / ...输入,这些输入无法通过PHP解码为$ _POST 一些例子:通过邮寄JSON字符串发送function fn(){var js_o…

绑定dictionary 给定关键字不再字典中_对字典嵌套的理解及二级下拉菜单的制作...

大家好,今日我们继续讲解VBA数组与字典解决方案,今日讲解第51讲:对字典嵌套的理解及二级下拉菜单的制作.在讲字典的时候,我反复说明,字典看视非常简单,由于它具有直达性可以省略去我们大量的循环查找代码,所以使用起来要特别留意很多用法和常…

C语言小笔记

C99标准下可以指定结构体的成员初始化。typedef struct{int a;int b; } Test;Test test {.a 10, .b 15};C99标准下可以指定数组下标初始化。int a[5] { [2] 5, 6, [4] 7 };方便的数据打印。打印一个整型值数据:int count 10; printf("count %d\n"…

lua中keyvalue_40行中的持久性KeyValue Server和一个可悲的事实

lua中keyvalue再次出现。..彼得斯撰写了有关Unsafe用法的书面概述 ,我将简要介绍一下Java中的低级技术如何通过启用更高级别的抽象或允许Java性能级别来节省开发工作可能很多人都不知道。 我的主要观点是表明,将对象转换为字节,反之亦然是一…

C++基础教程示例详解:C++中的I/O重定向

在C语言中,我们可以使用函数freopen()将现有文件指针重定向到另一个流。freopen()的原型如下FILE * freopen ( const char * filename, const char * mode, FILE * stream );例如,要将stdout重定向为文本文件,我们可以编写freopen ("tex…

租房界的php,php实现出租房数据管理及搜索页面

这篇文章主要为大家详细介绍了php出租房数据管理及搜索页面的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下php数据访问例子:租房信息管理,具体内容如下1.数据库建表2. zufangzi.php租房子区域:全选requi…

ln函数怎么看奇偶性_Python中函数的参数应该怎么理解?看完这篇文章情不自禁的想收藏...

前面给大家讲过,函数是一种编程思想,是提高代码重复利用的设计思路,是代码设计更深层次的产物。今天要给大家讲的就是函数的核心:函数的参数基本概念1、函数的参数:是指函数完成某项功能所需要的信息。举个例子&#x…

centos7.4编译mysql5.6,centos7编译安装mysql5.6

1.useradd -s /sbin/nologin -M mysql #新增mysql运行用户2.yum -y install ncurses-devel libaio-devel cmake gcc-c #安装依赖包3.编译,注:重新cmake需要删除CMakeCache.txt文件cmake -DCMAKE_INSTALL_PREFIX/zhonghong/mysql \-DMYSQL_DATADIR/zhong…

面向对象设计思想-C语言

面向对象的三个特征:封装,继承,多态。但是C语言不是面向对象编程语言,所以需要借助一些技巧来实现这三个特征:(1)C语言没有成员函数,struct只能封装数据,不能封装方法&am…

java iterable_太糟糕了,Java 8没有Iterable.stream()

java iterable这是最近比较有趣的Stack Overflow问题之一: 为什么Iterable不提供stream()和parallelStream()方法? 最初,直接将Iterable转换为Stream似乎很直观,因为在90&#xff…

three.js加载3d模型_基于WebGL的3D技术在网页中的运用 ThingJS 前端开发

Three.js、ThingJS这些引擎库可以加载3D制作软件的模型&#xff0c;大幅度提高了制作效率&#xff0c;改变WebGL开发困难的局面&#xff0c;让Web开发者享受便捷的3D开发服务。三者的难度对比如下&#xff1a;ThingJS&#xff08;框架&#xff09;< Three.js&#xff08;引擎…

C语言 | typedef

C语言typedef用新的类型名代替原有的类型名//指定用Integer为类型名&#xff0c;作用与int相同。 typedef int Integer&#xff1b;//指定用Real为类型名&#xff0c;作用与float相同。 typedef float Real&#xff1b;C语言允许程序设计者用一个简单的名字代替复杂的类型形式命…

php珠心算源码,深度解析珠心算的“开智”功能

编者按&#xff1a;本文来自李绵军校长在廊坊智慧特训营演讲。李绵军校长通过十几年来对珠心算的钻研练习&#xff0c;详细解读了珠心算的开智功能&#xff0c;以及“一门深入”的作用。珠心算的开智价值是在哪里&#xff1f;大家都说开发智力&#xff0c;我在这讲开发智力不是…

jsr 269 api_研究Java 9 Money and Currency API(JSR 354)

jsr 269 apiJSR 354定义了一个用于处理货币和货币的新Java API&#xff0c;计划将其包含在Java 9中。在本文中&#xff0c;我们将研究参考实现的当前状态&#xff1a; JavaMoney 。 就像我关于Java 8日期/时间API的帖子一样&#xff0c;该帖子将主要由显示新API的代码驱动。 …

python程序调试题_关于python程序调试问题,一个文件计算的问题

那位大神帮小弟看下这段代码有什么需要改进的没有。程序要求为&#xff1a;程序主要内容是&#xff1a;大地坐标经纬度的格式转换问题&#xff0c;例如12030′30″转换为120.50833333&#xff0c;并且可以互换&#xff0c;这样的程序。...那位大神帮小弟看下这段代码有什么需要…

C语言 函数

定义函数在 C 语言中&#xff0c;函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分&#xff1a;返回类型&#xff1a;一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值&#xff0c;在这种情况下&#xff…

cassandra 入门_Apache Cassandra和Java入门(第二部分)

cassandra 入门要求 要遵循本教程&#xff0c;您应该已经有一个正在运行的Cassandra实例&#xff08; 一个小型集群会很好 &#xff0c;但不是必需的&#xff09;&#xff0c;已安装Datastax Java驱动程序&#xff08; 请参阅第I部分 &#xff09;&#xff0c;并且已经在这里进…