>백엔드 개발 >파이썬 튜토리얼 >Python이 이메일 데이터를 읽고 첨부 파일을 다운로드하는 방법에 대한 자세한 설명

Python이 이메일 데이터를 읽고 첨부 파일을 다운로드하는 방법에 대한 자세한 설명

黄舟
黄舟원래의
2017-08-03 15:41:104729검색

이 글에서는 Python이 이메일 데이터를 읽고 첨부 파일을 다운로드하는 예제에 대한 자세한 설명을 중심으로 관련 정보를 소개합니다. 이 부분의 내용을 모두가 배우고 이해할 수 있도록 구현 예제를 소개합니다.

이메일 읽기 Python 구현에 대한 자세한 설명 데이터 및 다운로드 첨부 예

구현 결과 다이어그램:

구현 코드:


#!/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对象获取编码:
  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存在于根对象上:
  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&#39;%s <%s>&#39; % (name, addr)
        if header == &#39;From&#39;:
          from_address = value
          headers[&#39;from&#39;] = from_address
        else:
          to_address = value
          headers[&#39;to&#39;] = to_address
  content_type = msg.get_content_type()
  print &#39;head content_type: &#39;, content_type
  return headers


# indent用于缩进显示:
def get_email_cntent(message, base_save_path):
  j = 0
  content = &#39;&#39;
  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, &#39;wb&#39;)
      attachment_files.append(filename)
      att_file.write(data)
      att_file.close()
    elif contentType == &#39;text/plain&#39; or contentType == &#39;text/html&#39;:
      # 保存正文
      data = part.get_payload(decode=True)
      charset = guess_charset(part)
      if charset:
        charset = charset.strip().split(&#39;;&#39;)[0]
        print &#39;charset:&#39;, charset
        data = data.decode(charset)
      content = data
  return content, attachment_files


if __name__ == &#39;__main__&#39;:
  # 输入邮件地址, 口令和POP3服务器地址:
  emailaddress = &#39;xxxxxx@163.com&#39;
  # 注意使用开通POP,SMTP等的授权码
  password = &#39;xxxxxx&#39;
  pop3_server = &#39;pop.163.com&#39;

  # 连接到POP3服务器:
  server = poplib.POP3(pop3_server)
  # 可以打开或关闭调试信息:
  # server.set_debuglevel(1)
  # POP3服务器的欢迎文字:
  print server.getwelcome()
  # 身份认证:
  server.user(emailaddress)
  server.pass_(password)
  # stat()返回邮件数量和占用空间:
  messagesCount, messagesSize = server.stat()
  print &#39;messagesCount:&#39;, messagesCount
  print &#39;messagesSize:&#39;, messagesSize
  # list()返回所有邮件的编号:
  resp, mails, octets = server.list()
  print &#39;------ resp ------&#39;
  print resp # +OK 46 964346 响应的状态 邮件数量 邮件占用的空间大小
  print &#39;------ mails ------&#39;
  print mails # 所有邮件的编号及大小的编号list,[&#39;1 2211&#39;, &#39;2 29908&#39;, ...]
  print &#39;------ octets ------&#39;
  print octets

  # 获取最新一封邮件, 注意索引号从1开始:
  length = len(mails)
  for i in range(length):
    resp, lines, octets = server.retr(i + 1)
    # lines存储了邮件的原始文本的每一行,
    # 可以获得整个邮件的原始文本:
    msg_content = &#39;\n&#39;.join(lines)
    # 把邮件内容解析为Message对象:
    msg = Parser().parsestr(msg_content)

    # 但是这个Message对象本身可能是一个MIMEMultipart对象,即包含嵌套的其他MIMEBase对象,
    # 嵌套可能还不止一层。所以我们要递归地打印出Message对象的层次结构:
    print &#39;---------- 解析之后 ----------&#39;
    base_save_path = &#39;/media/markliu/Entertainment/email_attachments/&#39;
    msg_headers = get_email_headers(msg)
    content, attachment_files = get_email_cntent(msg, base_save_path)

    print &#39;subject:&#39;, msg_headers[&#39;subject&#39;]
    print &#39;from_address:&#39;, msg_headers[&#39;from&#39;]
    print &#39;to_address:&#39;, msg_headers[&#39;to&#39;]
    print &#39;date:&#39;, msg_headers[&#39;date&#39;]
    print &#39;content:&#39;, content
    print &#39;attachment_files: &#39;, attachment_files

  # 关闭连接:
  server.quit()

위 내용은 Python이 이메일 데이터를 읽고 첨부 파일을 다운로드하는 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.