总体来说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.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
body=email.MIMEText.MIMEText('这里是邮件内容',_subtype='plain',_charset='gb2312')
to: [email protected] from: [email protected] 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==--
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)