`
netcome
  • 浏览: 482811 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用Python处理邮件

阅读更多

总体来说python处理邮件还是比较方便的,库提供了很多工具.下面我把心得写出来,给新手一个启迪,也请高手给些更好的方法. 
先说接受邮件.  poplib 方法. 
1.poplib.POP3('这里填入你pop邮件服务器地址') 登陆服务器. 
2.poplib.user('用户名 ') poplib.pass_('密码') 
3.poplib.stat()方法返回一个元组:(邮件数,邮件尺寸) 
   mailCount,size=poplib.stat() 
   这样mailCount就是邮件的数量,size,就是所有邮件的大小. 

3.poplib.rert('邮件号码')方法返回一个元组:(状态信息,邮件,邮件尺寸)  
  hdr,message,octet=server.retr(1) 读去第一个邮件信息. 
   hdr的内容就是响应信息和邮件大小比如'+OK 12498 octets' 
   message 是包含邮件所有行的列表. 
   octet 是这个邮件的内容. 

 得到的message是邮件的原始内容,也就是没有解码过的,里面的内容和标题基本上都是base64编码的,下面说说如何处理原始邮件. 
python 的email库里提供了很多处理邮件的方法,我们先把原始邮件转成email实例,这样就可以用库方法处理邮件. 
email.message_from_string() 这个方法能把String的邮件转换成email.message实例. 
比如我们上面的message,向下面这样调用. 
mail=email.message_from_string(string.join(message,'\n')) 
这样我们就生成了一个email.Message实例 

现在我们来提取邮件内容,和标题,mail支持字典操作.比如下面的操作. 
mail['subject'] ,mail.get('subject') 
mail['To'],mail.get('to')' 
mail.keys() ,mail.items() 等等. 

中文邮件的标题和内容都是base64编码的.解码可以使用email.Header 里的decode_header()方法. 
比如 print mail['subject']   显示的都未处理的编码. 
'=?GB2312?B?UmU6IFtweXRob24tY2hpbmVzZV0g?=\n\t=?GB2312?B?y63E3LDvztLV0tbQzsS1xFBZVEhPTrP10afRp8+wtcTXysHP?=' 

email.Header.decode_header(mail['subject']) 下面是解码后的信息. 
[('Re: [python-chinese] \xcb\xad\xc4\xdc\xb0\xef\xce\xd2\xd5\xd2\xd6\xd0\xce\xc4\xb5\xc4PYTHON\xb3\xf5\xd1\xa7\xd1\xa7\xcf\xb0\xb5\xc4\xd7\xca\xc1\xcf', 'gb2312')] 
返回的是一个列表,里面的内容保存在一个元组里,(解码后的字串,字符编码) 

显示解码后的标题就象下面这样 
print email.Header.decode_header(mail['subject'])[0][0] 
Re: [python-chinese] 谁能帮我找中文的PYTHON初学学习的资料 

上面的mail标题编码是'gb2312'的,在我的winxp机器上可以直接显示,如果编码是别的比如'utf-8'编码,那么显示出来的就是乱码了.所以我们需要使用unicode()方法,unicode('这里是string','这里是编码,比如UTF-8'),比如 
subject=email.Header.decode_header(mail['subject'])[0][0] 
subcode=email.Header.decode_header(mail['subject'])[0][1]) 

print unicode(subject,subcode) 
Re: [python-chinese] 谁能帮我找中文的PYTHON初学学习的资料 

下面看如何处理邮件内容. 
mail里有很多方法,熟悉这些方法处理邮件就很容易了。 
get_payload() 这个方法可以把邮件的内容解码并且显示出来.第一个可选择参数是mail实例,第二个参数是decode='编码' ,一般都是,'base64'编码 
is_multipart(),这个方法返回boolean值,如果实例包括多段,就返回True, 
print mail.is_multipart() 
true  ,这说明这个mail邮件包含多个字段。我下面的函数就可以处理,显示邮件的全部内容。 

def showmessage(mail):

    if mail.is_multipart():

        for part in mail.get_payload():

            showmessage(part)

    else:

        type=mail.get_content_charset()

        if type==None:

            print mail.get_payload()

        else:

            try:

                print unicode(mail.get_payload('base64'),type)

            except UnicodeDecodeError:

                print mail



最后,有点要说明,如果邮件里的中文用mail.Header.decode_header()方法,和unicode()方法都不能正常显示,那么说明这个中文无法处理了,显示出来就是乱码.比如:看看看见,最终处理完成后,还是乱麻。 
>;>;>;mail.get('subject')

'Re: [python-chinese] =?UTF-8?B?wrnDmMOTw5p4bWzCscOgw4LDq8K1w4TDjg==?=\n\t=?UTF-8?B?w4rDjMOi?='

>;>;>;decode_header( mail.get('subject'))

[('Re: [python-chinese]', None), ('\xc2\xb9\xc3\x98\xc3\x93\xc3\x9axml\xc2\xb1\xc3\xa0\xc3\x82\xc3\xab\xc2\xb5\xc3\x84\xc3\x8e\xc3\x8a\xc3\x8c\xc3\xa2', 'utf-8')]

>;>;>;print decode_header( mail.get('subject'))[1][0]

鹿脴脫脷xml卤脿脗毛碌脛脦脢脤芒

>;>;>;print unicode(decode_header( mail.get('subject'))[1][0],'utf-8')

1?óúxml±à??μ??êìa





 jasonnbfan 回复于:2005-07-11 20:22:35

下面说说发送邮件,其实我感觉发送比接收邮件要容易。还是使用mail.Message里的方法。我们一步一步来。 
1:发送一个普通的文本邮件。 
msg=mail.Message.Message()    #一个实例 
msg['to']='love@python.com'      #发送到哪里 
msg['from']='my@email.com'       #自己的邮件地址 
msg['date']=time.ctime()             #时间日期 
msg['subject']=email.Header.Header('邮件主题','gb2312') 
#这里用Header方法处理subject. 
完成后的样子. 
>;>;>;print msg.as_string() 
to: love@python.com 
from: my@email.com 
date: Mon Jul 11 20:18:13 2005 
subject: =?gb2312?b?08q8/tb3zOI=?=  

下面开始写内容。 
body=email.MIMEText.MIMEText('这里是邮件内容',_subtype='plain',_charset='gb2312')


MIMEText()方法包括3个参数,内容,_subtype类型,_charset字符编码,完成后的样子: 
>;>;>;print body.as_string() 
Content-Type: text/plain; charset="gb2312" 
MIME-Version: 1.0 
Content-Transfer-Encoding: base64 

1eLA78rHxNrI3Q== 

Content-Type,说明内容类型,这里是txt/plain,纯文本类型。如果添加附件 
那么就是Application/octet-stream 
Content-Transfer-Encoding这个就是编码类型,这里是base64,现在的email都是base64编码 

写完以后如何组合起来?mail有一个as_string()方法,顾名思义。显示成一个字符串.我上面也用了。smtplib里的sendmail()方法里需要的是字符串类型。所以我们这里可以这样: 完整的内容加起来就行了。 
>;>;>;print msg.as_string()+body.as_string() 
to: love@python.com 
from: my@email.com 
date: Mon Jul 11 20:18:13 2005 
subject: =?gb2312?b?08q8/tb3zOI=?= 

Content-Type: text/plain; charset="gb2312" 
MIME-Version: 1.0 
Content-Transfer-Encoding: base64 

1eLA78rHxNrI3Q== 

如何发送. 
server=smtplib.SMTP('smtp.mail.yahoo.com')  #你发送服务器的地址 
server.login('username','password')       #用户名和密码 
server.sendmail('from','to','msg.as_string()[:-1]+body.as_string()') 
#这样就完成了邮件的发送. 
有一点要注意.只有内容前面有一个空行,其他的地方都不能有空行.前面我们直接print msg.as_string()+body.as_string()可以看见在subject: 和Content-type:这里有一个空行,所以我用'msg.as_string()[:-1]把多余的空行去掉.让他和body保持格式. 

下面看看如何发带附件的邮件,和上面差不多. 
attach=mail.MIMEMultipart.MIMEMultipart()  #这里创建一个带附件的实例 
attach.attach(body)  #把我们刚才写的邮件内容加进去. 

attachment=MIMEText(open('myself.py','r').read(),'base64') 
#第一个参数打开文件read()方法读出所有内容,刚好是字符串格式,第二个参数是希望的编码,这种方法比较简单. 

attachment.replace_header('Content-type','Application/octet-stream;name="myself.py"') 
#前面讲过Content-type:他的值可以是text/plain text/heml 等等,如果是附件,就是Application/octet-stream,后面的;name="myself.py"是附件的文件名.默认的MIMEText()后这里的内容是text/plain的,所以需要替换 

attachment.add_header('Content-Disposition','attachment;filename="myself.py") 
#这里添加一个标题,Content-Disposition,attachment说明是一个附件,filename说明文件名.mail里有一个get_filename()的方法可以得到附件里的文件名. 

attach.attach(attachment)  #现在我们把编码好的附件也加进去 

完成后的邮件像下面这样 
to: asdf@tom.com

from: asdf@tom.com

subject: =?gb2312?b?1vfM4g==?=

Content-Type: multipart/mixed; boundary="===============0572491976=="

MIME-Version: 1.0


--===============0572491976==

Content-Type: text/plain; charset="gb2312"

MIME-Version: 1.0

Content-Transfer-Encoding: base64


1eLA78rHxNrI3Q==


--===============0572491976==

Content-Type: Application/octet-stream;name="myself.py"

MIME-Version: 1.0

Content-Transfer-Encoding: base64

Content-Disposition: attachment;filename="myself.py"


ZnJvbSBlbWFpbC5NSU1FVGV4dCBpbXBvcnQgTUlNRVRleHQKZnJvbSBlbWFpbC5NSU1FTXVsdGlw

YXJ0IGltcG9ydCBNSU1FTXVsdGlwYXJ0CmZyb20gZW1haWwuSGVhZGVyIGltcG9ydCBIZWFkZXIK

ZnJvbSBlbWFpbC5IZWFkZXIgaW1wb3J0IGRlY29kZV9oZWFkZXIKZnJvbSB0eXBlcyBpbXBvcnQg

--===============0572491976==--



好了,可以发送了. 
server=smtplib.SMTP('smtp.mail.yahoo.com')   
server.login('username','password')        
server.sendmail('from','to','msg.as_string()[:-1]+attach.as_string()') 

刚才说了,附件也可以不用MIMEText()方法创建像下面这样也可以. 
att=base64.encodestring(open('file','r').read()) 
att=MIMEText(att) 
然后就和前面一样,换标题Content-type, 加Content-Disposition标题,等等.显然比较麻烦. 

当然更简单的方法就是创建上面的attach以后,直接在attach里添加 主题等标题. 
attach['to']='asdf@tom.com' 
attach['from']='asdfd@tom.com' 
attach['date']=time.ctime() 
attach['subject']=Header('直接发送的标题','gb2312') 
这样添加完以后直接attach.as_string()发送就可以了,包括了主题,内容,附件. 

全文完,菜鸟学习经过,仅供新手参考. 

希望高手能多多指点.


 jasonnbfan 回复于:2005-07-11 21:40:33

发现自己的表达能力太差,看来要多练练,大家将就着看好了。 
这个星期研究Tk学会了写个GUI界面的邮件程序.学好了再上来写心得.


 jasonnbfan 回复于:2005-07-11 21:44:34

最后把我写的一个简陋的,幼稚的一个字符平台的email程序贴上来.希望高手能给指点指点. 
程序的菜单截面根据Programming Python ed2,里面的程序改的,否则我肯定是想不出来这样的菜单截面.(想象力差,还是经验不足,晕) 

保存邮件方法没有做出来.发送邮件也没写.
from email.MIMEText import MIMEText

from email.MIMEMultipart import MIMEMultipart

from email.Header import Header

from email.Header import decode_header

from types import *

import smtplib,poplib,string,sys,os,email



helptext = """

Available commands:

i     - index display

l n?  - list all messages (or just message n)

d n?  - mark all messages for deletion (or just message n)

s n?  - save input num messages to a file (or just message n)

m     - compose and send a new mail message

q     - quit pymail

?     - display this help text

"""

#简单的菜单处理,无返回值,要求一个处理过的mail列表

def interact(processmail):

    #showindex(processmail)

    while 1:

        try:

            command=raw_input('[Pymail] Action? (i, l, d, s, m, q, ?) ')

        except EOFError:

            command='q'


        if command=='q' or not command:

            break


        elif command[0]=='i':

            showindex(processmail)


        elif command[0]=='l':

            if len(command)==1:

                for mail in processmail:

                    showmessage(mail)

                    print string.join(message)

            else:

                if 0<msgnum(command)<=len(processmail):

                    num=msgnum(command)

                    showsubject(processmail[num-1])

                    showmessage(processmail[num-1])

        elif command[0]=='s':

            if len(command)==1:

                print '请输入要保存的邮件号码'

                continue

            else:

                if 0<msgnum(command)<=len(processmail):

                    num=msgnum(command)

                    savemail(processmail[num-1])


        elif command[0]=='?':

            print helptext


        else:

            print 'What? -- type "?" for commands help'


 #保存email未完成           

def savemail(mail):

    filename=raw_input('Enter a file name:')

    file=open('filename','w')

    print >;>; file,showsubject(mail),showmessage(mail)

    print 'saving mail to %s ok.' %(filename)


#处理输入的数字   

def msgnum(command):

    try:

        return string.atoi(string.split(command)[1])

    except:

        return -1


#用于接收 邮件的相关处理,返回一个server实例   

def POPconnect():

    sname,user,passwd=popconfig()

    server=poplib.POP3(sname)

    server.user(user)

    server.pass_(passwd)

    print server.getwelcome()

    return server


#用于发送 邮件的相关处理,返回一个server实例 

def SMTPconnect():

    server=smtplib.SMTP(sname)

    server.login(user,passwd)

    return server


#从服务器读取邮件到maillist.列表,位处理的原始字符串

def loadmail():

    server=POPconnect()

    try:

        print server.list()

        (mailCount,mailByte)=server.stat()

        print 'There are',mailCount,'mail messages in',mailByte,'bytes'

        print 'Retrieving:'

        mailList=[]

        for i in range(mailCount):

            print i+1,

            (hdr,message,octet)=server.retr(i+1)

            mailList.append(string.join(message,'\n'))

        print

        assert len(mailList)==mailCount

        return mailList


    finally:

        server.quit()


#处理loadmain返回的原始mail列表,返回处理过的processmail列表

def processmail(mailList):

    processmaillist=[]

    for i in range(len(mailList)):

        processmaillist.append(email.message_from_string(mailList))

    return processmaillist


#显示邮件主题,要求一个处理过的mail做参数

def showsubject(mail):

    header=[]

    for head in decode_header(mail.get('subject')):

        if head[1]=='utf-8':

            header.append(unicode(head[0],'utf-8'))

        else:

            header.append(head[0])

            

    for sub in ('From','Date','Subject'):

        if sub=='Subject':

            print 'Subject:',

            for subject in header:

                try:

                    print subject,

                except UnicodeEncodeError:

                    print '注意:这个邮件标题无法正常显示...'

        else:

            print '%s:%s' %(sub,mail[sub])

    print      

        

#显示邮件内容,要求一个处理过的mail做参数

def showmessage(mail):

    if mail.is_multipart():

        for part in mail.get_payload():

            showmessage(part)

    else:

        type=mail.get_content_charset()

        if type==None:

            print mail.get_payload()

        else:

            try:

                print unicode(mail.get_payload(decode='base64'),type)

            except UnicodeDecodeError:

                print mail


#显示全部邮件主题要求整个处理过的邮件列表

def showindex(processmaillist):

    count=1

    for mail in processmaillist:

        print count,

        showsubject(mail)

        print 

        if count%5==0:

            raw_input("\n[Press Enter key]")

        count+=1


#输入发送时需要的服务器名等相关信息,返回一个元组

def sendconfig():

    SMTPname=raw_input('SMTPserverName?')

    SMTPuser=raw_input('SMTPusername?')

    SMTPpass=raw_input('SMTPServerPassword?')

    To=raw_input('To?')

    From=raw_input('From?')

    return SMTPname,SMTPuser,SMTPpass,to,From


#输入接收邮件时需要的相关输入,返回一个元组

def popconfig():

   POPname=raw_input('POPServerName?')

   POPuser=raw_input('POPusername?')

   POPpass=raw_input('POPpassword?')

   return POPname,POPuser,POPpass


if __name__=='__main__':

    list=loadmail()

    maillist=processmail(list)

    interact(maillist)

    







 nfqx 回复于:2005-07-12 09:09:12

鼓励一下


 bleem1998 回复于:2005-07-12 09:20:57

very good


 xichen 回复于:2005-07-12 09:23:46

对于汉字编码的转换,可以这样做,我试过效果不错。 
a='中国' 
a.decode('gb2312').encode("utf-8")


 guotie 回复于:2006-06-27 11:17:03

very good ! 

thanks!


 kai0200 回复于:2006-06-27 22:13:30

鼓励一下 
帮你顶一下,向你学习!

[ 本帖最后由 kai0200 于 2006-7-4 22:22 编辑 ]


 guotie 回复于:2006-08-28 14:58:22

请教一个问题,如何判断邮件的附件? 

btw,楼主的showmessage()用walk()来实现似乎更好一点。


 guotie 回复于:2006-08-29 14:56:54

判断某个part的编码应该使用Content-Transfer-Encoding。


 guotie 回复于:2006-08-29 16:27:48

处理邮件内容时,这样做更好一些: 
参数mail是通过message_from_string()得到的instance 

def mail_content(mail): 
    content =    '' 
    for part in mail.walk(): 
        if part.is_multipart(): 
            continue 

        ch =    part.get_content_charset() 
        if ch: 
            content +=    unicode(part.get_payload(decode = True),ch).encode('utf-8') 
        else: 
            content +=    part.get_payload(decode = True).decode('gb2312').encode('utf-8') 

    return content

分享到:
评论

相关推荐

    Python实现邮箱自动化处理

    Python实现邮箱(以QQ邮箱为例)自动化处理,包括自动发送、读取、删除、定时发送等等 目录 1 模块介绍与安装 2 利用Python发送邮件 2.1 发送一封简单的电子邮件 2.2 发送含HTML样式的电子邮件 2.3 发送带附件的...

    基于Python的邮件分类系统 开题报告.docx

    基于Python的邮件分类系统旨在解决这一问题,通过自动化的方式,对邮件进行有效分类,提升用户的邮件处理效率,减轻网络资源的浪费。 一、系统设计目的与意义 1. 目的:邮件分类系统的核心目标是通过智能算法对...

    python实现下载pop3邮件保存到本地

    Python实现下载pop3邮件保存到本地的知识点涉及到使用Python进行网络编程,利用poplib模块与邮件服务器交互,以及使用正则表达式处理邮件内容。以下是详细介绍: 1. poplib模块介绍: poplib是Python标准库的一部分...

    基于Python实现多进程的发送邮件.zip

    尤其在处理耗时较长的任务,如发送大量邮件时,使用多进程可以显著缩短整体处理时间。本课程设计的目标是利用Python实现多进程发送邮件的功能。 首先,我们需要了解Python中的`multiprocessing`模块,它是Python...

    Python发邮件源码

    这里我们关注的主题是“Python发邮件源码”,这通常涉及到使用SMTP(Simple Mail Transfer Protocol)来实现邮件的发送。下面我们将深入探讨这个话题,并提供一个实际的Python代码示例。 首先,你需要了解Python中...

    python邮件发附件方法

    Python 邮件发附件方法是指使用 Python 语言发送带附件的电子邮件。该方法使用了 Python 的 email 模块,通过该模块可以创建一个带附件的邮件实例,并将其发送到指定的收件人邮箱中。 email 模块是 Python 的一个...

    Python-PostMail一个简单的邮件服务器可以让你发送一个邮件只发送一个POST请求

    PostMail会自动处理邮件的编码、格式化,并通过SMTP服务器发送出去。默认情况下,PostMail使用本地SMTP服务器,但你可以通过配置文件或POST请求中的参数来指定其他SMTP服务器。 在实际项目中,你可能需要更复杂的...

    python爬虫发邮件示例demo

    Python爬虫技术是一种广泛应用于数据抓取和自动化处理的编程工具,它可以帮助我们从互联网上获取大量信息。在这个“python爬虫发邮件示例demo”中,我们将探讨如何结合Python的爬虫技术和邮件发送功能,实现自动抓取...

    python垃圾邮件过滤利用贝叶斯分类器写的垃圾邮件过滤器,准确率达98.zip

    在垃圾邮件过滤中,我们训练模型识别垃圾邮件和非垃圾邮件的特征,然后用这些特征来预测新邮件的类别。 1. **基础概念**:贝叶斯分类器首先假设特征之间相互独立,然后通过训练数据计算每个特征在垃圾邮件和非垃圾...

    Python-email下载器将邮件以eml文件格式备份到本地

    通过研究这些代码,开发者可以学习如何使用Python进行邮件处理,以及如何组织和部署这样的脚本。 总的来说,Python的`imaplib`和`email`库为创建电子邮件下载器提供了强大的工具,使得开发者可以轻松地备份和管理...

    Python-python发送邮件报表

    通过以上步骤,你可以用Python编写一个脚本来定期自动发送包含报表的邮件,这对于日常的数据报告或者监控报警非常有用。在`Python_SentEmailExcel-master`这个项目中,可能包含了完整的示例代码和更多的功能,例如...

    基于Python的电子邮件自动发送程序设计.pdf

    Python标准库中提供了smtplib和email模块,可以用来处理电子邮件的发送,但这些模块在处理邮件格式构造时较为繁琐。 其次,邮件发送协议包括SMTP(Simple Mail Transfer Protocol)和POP3(Post Office Protocol ...

    Python-MailinaBox一键轻松部署邮件服务器

    它处理邮件的发送和接收,遵循标准的SMTP协议。 3. **IMAP服务器**:用于接收邮件,项目使用 Dovecot 作为IMAP服务器,让用户可以通过邮箱客户端访问和管理邮件。 4. **Webmail**:Mail-in-a-Box 提供 Roundcube ...

    Python-Python实现自动发邮件支持HTML富文本

    在实际应用中,还可以根据需要添加错误处理和重试机制,以提高邮件发送的可靠性。 在提供的压缩包`python-emailer-master`中,可能包含了实现以上功能的完整示例代码或者一个简单的邮件发送脚本。解压后,通过阅读...

    使用python群发邮件

    在IT行业中,Python是一种强大的编程语言,其丰富的库支持使得执行各种任务变得极其方便,包括自动化任务和数据处理。在本场景中,我们将探讨如何利用Python进行邮件群发,这在营销、通知或者日常沟通中都非常实用。...

    Python使用POP3和SMTP协议收发邮件的示例代码

    # 处理邮件内容 # (此处略去对邮件内容的处理逻辑) ``` 在这个例子中,`retr()`方法用于下载指定编号的邮件。通过循环遍历邮件列表并逐个下载,即可获取所有的邮件内容。 #### 五、总结 通过上述示例代码可以看出...

    python+POP3实现批量下载邮件附件

    本文主要介绍了如何使用Python编程语言配合POP3协议来实现批量下载邮箱中的邮件附件。以下是对本文内容的详细解读,包括知识点、技术细节和操作步骤。 知识点一:Python的基础使用和第三方库 Python是一种广泛使用...

    Python-Salmon是一个纯Python邮件服务器旨在以现代web框架的风格创建健壮且复杂的邮件应用

    2. **可扩展性**:借鉴Web框架的设计,Salmon支持插件系统,允许开发者根据需求编写自定义插件来处理邮件事件,如过滤、分析或转发邮件。 3. **路由和中间件**:类似于Web框架中的路由规则,Salmon允许设定规则来...

    Python实现自动发送邮件和发送钉钉消息源码

    本篇将深入讲解如何利用Python的requests库发送钉钉消息以及如何使用email和smtplib库发送邮件,特别是与163邮箱服务的集成。 首先,我们来探讨如何使用requests库发送钉钉消息。钉钉提供了Webhook接口,通过...

Global site tag (gtag.js) - Google Analytics