詳解python實(shí)現(xiàn)讀取郵件數(shù)據(jù)并下載附件的實(shí)例
詳解python實(shí)現(xiàn)讀取郵件數(shù)據(jù)并下載附件的實(shí)例
實(shí)現(xiàn)結(jié)果圖:

實(shí)現(xiàn)代碼:
#!/usr/bin/python2.7
# _*_ coding: utf-8 _*_
"""
@Author: MarkLiu
"""
import poplib
import email
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
def decode_str(s):
value, charset = decode_header(s)[0]
if charset:
value = value.decode(charset)
return value
def guess_charset(msg):
# 先從msg對(duì)象獲取編碼:
charset = msg.get_charset()
if charset is None:
# 如果獲取不到,再從Content-Type字段獲取:
content_type = msg.get('Content-Type', '').lower()
pos = content_type.find('charset=')
if pos >= 0:
charset = content_type[pos + 8:].strip()
return charset
def get_email_headers(msg):
# 郵件的From, To, Subject存在于根對(duì)象上:
headers = {}
for header in ['From', 'To', 'Subject', 'Date']:
value = msg.get(header, '')
if value:
if header == 'Date':
headers['date'] = value
if header == 'Subject':
# 需要解碼Subject字符串:
subject = decode_str(value)
headers['subject'] = subject
else:
# 需要解碼Email地址:
hdr, addr = parseaddr(value)
name = decode_str(hdr)
value = u'%s <%s>' % (name, addr)
if header == 'From':
from_address = value
headers['from'] = from_address
else:
to_address = value
headers['to'] = to_address
content_type = msg.get_content_type()
print 'head content_type: ', content_type
return headers
# indent用于縮進(jìn)顯示:
def get_email_cntent(message, base_save_path):
j = 0
content = ''
attachment_files = []
for part in message.walk():
j = j + 1
file_name = part.get_filename()
contentType = part.get_content_type()
# 保存附件
if file_name: # Attachment
# Decode filename
h = email.Header.Header(file_name)
dh = email.Header.decode_header(h)
filename = dh[0][0]
if dh[0][1]: # 如果包含編碼的格式,則按照該格式解碼
filename = unicode(filename, dh[0][1])
filename = filename.encode("utf-8")
data = part.get_payload(decode=True)
att_file = open(base_save_path + filename, 'wb')
attachment_files.append(filename)
att_file.write(data)
att_file.close()
elif contentType == 'text/plain' or contentType == 'text/html':
# 保存正文
data = part.get_payload(decode=True)
charset = guess_charset(part)
if charset:
charset = charset.strip().split(';')[0]
print 'charset:', charset
data = data.decode(charset)
content = data
return content, attachment_files
if __name__ == '__main__':
# 輸入郵件地址, 口令和POP3服務(wù)器地址:
emailaddress = 'xxxxxx@163.com'
# 注意使用開通POP,SMTP等的授權(quán)碼
password = 'xxxxxx'
pop3_server = 'pop.163.com'
# 連接到POP3服務(wù)器:
server = poplib.POP3(pop3_server)
# 可以打開或關(guān)閉調(diào)試信息:
# server.set_debuglevel(1)
# POP3服務(wù)器的歡迎文字:
print server.getwelcome()
# 身份認(rèn)證:
server.user(emailaddress)
server.pass_(password)
# stat()返回郵件數(shù)量和占用空間:
messagesCount, messagesSize = server.stat()
print 'messagesCount:', messagesCount
print 'messagesSize:', messagesSize
# list()返回所有郵件的編號(hào):
resp, mails, octets = server.list()
print '------ resp ------'
print resp # +OK 46 964346 響應(yīng)的狀態(tài) 郵件數(shù)量 郵件占用的空間大小
print '------ mails ------'
print mails # 所有郵件的編號(hào)及大小的編號(hào)list,['1 2211', '2 29908', ...]
print '------ octets ------'
print octets
# 獲取最新一封郵件, 注意索引號(hào)從1開始:
length = len(mails)
for i in range(length):
resp, lines, octets = server.retr(i + 1)
# lines存儲(chǔ)了郵件的原始文本的每一行,
# 可以獲得整個(gè)郵件的原始文本:
msg_content = '\n'.join(lines)
# 把郵件內(nèi)容解析為Message對(duì)象:
msg = Parser().parsestr(msg_content)
# 但是這個(gè)Message對(duì)象本身可能是一個(gè)MIMEMultipart對(duì)象,即包含嵌套的其他MIMEBase對(duì)象,
# 嵌套可能還不止一層。所以我們要遞歸地打印出Message對(duì)象的層次結(jié)構(gòu):
print '---------- 解析之后 ----------'
base_save_path = '/media/markliu/Entertainment/email_attachments/'
msg_headers = get_email_headers(msg)
content, attachment_files = get_email_cntent(msg, base_save_path)
print 'subject:', msg_headers['subject']
print 'from_address:', msg_headers['from']
print 'to_address:', msg_headers['to']
print 'date:', msg_headers['date']
print 'content:', content
print 'attachment_files: ', attachment_files
# 關(guān)閉連接:
server.quit()
以上就是python讀取郵件并下載郵件附件的實(shí)例,如有疑問請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
keras.layers.Layer中無法定義name的問題及解決
這篇文章主要介紹了keras.layers.Layer中無法定義name的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
python對(duì)指定目錄下文件進(jìn)行批量重命名的方法
這篇文章主要介紹了python對(duì)指定目錄下文件進(jìn)行批量重命名的方法,涉及Python中replace及join方法的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
用Python給圖像算法做個(gè)簡(jiǎn)單應(yīng)用界面
這篇文章主要介紹了用Python給圖像算法做個(gè)簡(jiǎn)單應(yīng)用界面,幫助大家更好的理解和學(xué)習(xí)使用python開發(fā)gui,感興趣的朋友可以了解下2021-05-05
pytorch中transform.Compose()用法詳解
PyTorch是一個(gè)開源的Python機(jī)器學(xué)習(xí)庫,基于Torch,用于自然語言處理等應(yīng)用程序,這篇文章主要介紹了pytorch中transform.Compose()用法,需要的朋友可以參考下2023-10-10
Python發(fā)送網(wǎng)絡(luò)請(qǐng)求(requests)
這篇文章主要介紹了Python發(fā)送網(wǎng)絡(luò)請(qǐng)求(requests),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
使用Python開發(fā)個(gè)京東上搶口罩的小實(shí)例(僅作技術(shù)研究學(xué)習(xí)使用)
這篇文章主要介紹了使用Python開發(fā)個(gè)京東上搶口罩的小實(shí)例(僅作技術(shù)研究學(xué)習(xí)使用),需要的朋友可以參考下2020-03-03
django自定義Field實(shí)現(xiàn)一個(gè)字段存儲(chǔ)以逗號(hào)分隔的字符串
這篇文章主要介紹了django自定義Field實(shí)現(xiàn)一個(gè)字段存儲(chǔ)以逗號(hào)分隔的字符串的示例,需要的朋友可以參考下2014-04-04
Python實(shí)現(xiàn)多態(tài)、協(xié)議和鴨子類型的代碼詳解
問起面向?qū)ο蟮娜筇匦?,幾乎每個(gè)人都能對(duì)答如流:封裝、繼承、多態(tài)。今天我們就要來說一說Python實(shí)現(xiàn)多態(tài)、協(xié)議和鴨子類型,感興趣的朋友跟隨小編一起看看吧2019-05-05

