Разбор файлов mbox в Python

новичок Python здесь. Я хочу пройти через большой файл mbox, разбирая сообщения электронной почты. Я могу сделать это с:

import sys
import mailbox

def gen_summary(filename):
    mbox = mailbox.mbox(filename)
    for message in mbox:
       subj = message['subject']
       print subj

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print 'Usage: python genarchivesum.py mbox'
        sys.exit(1)

    gen_summary(sys.argv[1])

но мне нужно больше контроля. Мне нужно иметь возможность получить байтовую позицию начала данного письма в файле mbox, а также мне нужно получить количество байтов в сообщении (Как представлено на диске). И тогда в будущем, вместо итерации с начала файла mbox, мне нужно иметь возможность искать данное сообщение и просто анализировать его (следовательно одна из потребностей получения позиции байта на диске). Это большие файлы mbox и эффективность является проблемой.

цель всего этого заключается в том, чтобы я мог создать сводный файл, который содержит некоторые небольшие биты о каждом письме в mbox, а затем в будущем эффективно искать отдельные электронные письма в mbox.

1 ответов


Я не тестировал это, но что-то вроде этого может сработать для вас. Просто откройте файл (в двоичном режиме, чтобы ваши байты были правильными) и сканируйте его, находя сообщения.

def is_mail_start(line):
    return line.startswith("From ")

def build_index(fname):
    with open(fname, "rb") as f:
        i = 0
        b = 0
        # find start of first message
        for line in f:
            b += len(line)
            if is_mail_start(line):
                break
        # find start of each message, and yield up (index, length) of previous message
        for line in f:
            if is_mail_start(line):
                yield (i, b)
                i += b
                b = 0
            b += len(line)
        yield (i, b) # yield up (index, length) of last message

# get index as a list
mbox_index = list(build_index(fname))

как только у вас есть индекс, вы можете использовать .seek() метод на файловом объекте для поиска там и .read(length) на объекте file читать только одно сообщение. Я не уверен, как вы будете использовать mailbox модуль со строкой, хотя; я думаю, что он предназначен для работы на почтовом ящике на месте. Может быть, там это какой-то другой модуль разбора почты, который вы можете использовать.