天天看點

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

<a target="_blank" href="http://www.cnblogs.com/sislcb/archive/2008/12/01/1344860.html">python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)</a>

python自帶的email子產品是個很有意思的東西,它可以對郵件編碼解碼,用來處理郵件非常好用。

處理郵件是一個很細緻的工作,尤其是解碼郵件,因為它的格式變化太多了,下面先看看一個郵件的源檔案:

received: from 192.168.208.56 ( 192.168.208.56 [192.168.208.56] ) by

ajax-webmail-wmsvr37 (coremail) ; thu, 12 apr 2007 12:07:48 +0800 (cst)

date: thu, 12 apr 2007 12:07:48 +0800 (cst)

from: user1 &lt;[email protected]&gt;

to: zhaowei &lt;[email protected]&gt;

message-id: &lt;[email protected]&gt;

subject: =?gbk?b?u+njta==?=

mime-version: 1.0

content-type: multipart/alternative; 

boundary="----=_part_21696_28113972.1176350868319"

------=_part_21696_28113972.1176350868319

content-type: text/plain; charset=gbk

content-transfer-encoding: base64

ztls0b+qyrzs1m6qysfsu7j20mfg2ru70ru0zqos1k3atmrh0ru49ttctffsu7toztldx8/w1nrt

prjdysew67xjssxe3mji1ebc6bezicag

content-type: text/html; charset=gbk

content-transfer-encoding: quoted-printable

&lt;div&gt;=ce=d2=d2=d1=bf=aa=ca=bc=d2=d4=ce=aa=ca=c7=d2=bb=b8=f6=d0=c7=c6=da=bb=

=bb=d2=bb=b4=ce=a3=ac=d4=ad=c0=b4=ca=c7=d2=bb=b8=f6=d4=c2=b5=f7=d2=bb=b4=ce=

&lt;/div&gt;

&lt;div&gt;=ce=d2=c3=c7=cf=d6=d4=da=d3=a6=b8=c3=ca=c7=b0=eb=b5=e3=b2=c5=c4=dc=c8=

=c8&lt;/div&gt;

&lt;div&gt;=d5=e6=c2=e9=b7=b3&lt;/div&gt;

------=_part_21696_28113972.1176350868319--

上面的就是以封郵件的源檔案,從第一行到第一個空行之間的為信件頭,後面的就是信件體了。把上面的資訊複制下來存到一個叫xxx.eml的檔案裡,用滑鼠輕按兩下就可以看到内容,當然看到的是解碼後的,是outlook幫你解碼了。

看看email子產品怎麼處理這個郵件,假設信件已經存為xxx.eml。

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

#-*- encoding: gb2312 -*-

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

import email

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

fp = open("xxx.eml", "r")

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

msg = email.message_from_file(fp) # 直接檔案建立message對象,這個時候也會做初步的解碼

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

subject = msg.get("subject") # 取信件頭裡的subject, 也就是主題

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

# 下面的三行代碼隻是為了解碼象=?gbk?q?=cf=e0=c6=ac?=這樣的subject

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

h = email.header.header(subject)

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

dh = email.header.decode_header(h)

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

subject = dh[0][0]

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

print "subject:",

subject

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

print "from: ",

email.utils.parseaddr(msg.get("from"))[1] # 取from

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

print "to: ",

email.utils.parseaddr(msg.get("to"))[1] # 取to

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

fp.close()

這段代碼可以把一封郵件中的主題、發件人、收件人解析出來。email.utils.parseaddr是用來專門解析郵件位址的,原因是郵件位址很多時候在原文裡是這樣寫的:user1 &lt;[email protected]&gt;, email.utils.parseaddr就可以把它解析為一個清單,第一項是user1, 第二項是[email protected], 這裡隻顯示了後面以部分。

前面那段代碼隻是解析了信件頭,接着解析信件體吧。信體裡可能有純文字的plain和html兩部分,也可能有附件。這裡需要mime的知識,詳細介紹可以從網上搜搜。我這裡就不說了,下面看看怎麼解析的:

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

msg = email.message_from_file(fp)

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

# 循環信件中的每一個mime的資料塊

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

for par in msg.walk():

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 if not par.is_multipart(): # 這裡要判斷是否是multipart,是的話,裡面的資料是無用的,至于為什麼可以了解mime相關知識。

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 name = par.get_param("name") #如果是附件,這裡就會取出附件的檔案名

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 if name:

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 #有附件

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 # 下面的三行代碼隻是為了解碼象=?gbk?q?=cf=e0=c6=ac.rar?=這樣的檔案名

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 h = email.header.header(name)

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 dh = email.header.decode_header(h)

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 fname = dh[0][0]

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 print '附件名:',

fname

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 data = par.get_payload(decode=true) # 解碼出附件資料,然後存儲到檔案中

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 try:

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 f = open(fname, 'wb') #注意一定要用wb來打開檔案,因為附件一般都是二進制檔案

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 except:

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 print '附件名有非法字元,自動換一個'

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 f = open('aaaa', 'wb')

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 f.write(data)

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 f.close()

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 else:

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 #不是附件,是文本内容

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 print par.get_payload(decode=true) # 解碼出文本内容,直接輸出來就可以了。

python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)
python子產品之email: 電子郵件編碼解碼 (一、解碼郵件)

 print '+'*60 # 用來差別各個部分的輸出

簡單吧,并沒有多少代碼就可以實作複雜的解析郵件的功能!