2012-04-20 2 views
10

Python 초보자는 여기에 있습니다. 이메일 메시지를 파싱하면서 큰 mbox 파일을보고 싶습니다. 나는 다음과 같이 할 수있다 :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 내의 개별 이메일을 효율적으로 조회하는 것입니다.

+0

'mailbox'는 한번도 사용하지 않았지만'help (mailbox.mbox)'를 읽었습니다. '.iterkeys()'메서드를 사용하여 키 값의 반복자를 얻은 다음 키 값을 사용하여 메시지를 찾을 수 없습니까? 왜 바이트 인덱스를 키로 사용하여 모듈을 사용하는 대신 메시지를 찾고 싶습니까 ... 모듈을 사용하여 키로 메시지를 인덱싱하려고 했습니까? 당신이 그것을 시도하고 너무 느린 또는 뭔가 있다면, 그렇게 말하십시오. – steveha

+0

10,000 개의 이메일로 이루어진 mbox가 있다고 가정 해보십시오. 나는 단지 마지막 전자 메일을 원할 때 9,998 개를 읽거나/parse/iterate 할 필요가 없다. 그 점을 mbox 파일에서 찾고 그 메시지를 읽으 려합니다. –

+0

@MarkFletcher이게 효과가 있니? 그렇다면 알려주세요. – kingmakerking

답변

8

테스트하지는 않았지만이 방법을 사용하면 도움이 될 수 있습니다. 바이트 수가 정확하도록 이진 모드에서 파일을 열고 메시지를 검색하여 메시지를 찾습니다. 인덱스가 있으면

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 모듈을 문자열과 함께 사용하는 방법을 잘 모르겠습니다. 나는 그것이 장소에서 우체통에서 작동하기위한 것이라고 생각합니다. 어쩌면 사용할 수있는 다른 메일 파싱 모듈이있을 수 있습니다.

+1

감사합니다. 나는이 전략과 같은 것을 사용할 것이라고 생각한다. btw, mbox에서 이메일 시작은 'From'(:)없이 시작합니다. email.Parser를 사용하여 전자 메일을 구문 분석 할 수 있습니다. 감사. –

+0

답을 편집하여 ':'을 꺼내겠습니다. 나는 * 테스트를하지 않았다고 말했어 ... 당신의 프로젝트에 행운을 빈다. 좋은 주말 보내세요! – steveha

+0

미래의 사용자들에게 그것은 가치있는 일입니다. 적어도 OSX의 최신 버전에서는 실제로 둘 다 있습니다. def 시작 is_mail_start (행) : \t return line.startswith ("From")이 아니라 line.startswith ("From :") – adammenges