Разбор 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) в файловом объекте читать только одно сообщение. Я не уверен, как вы будете использовать модуль mailbox со строкой; Я думаю, что он предназначен для работы с почтовым ящиком на месте. Возможно, есть еще один модуль для разбора почты, который вы можете использовать.