2012-04-20 39 views
10

Người mới sử dụng Python tại đây. Tôi muốn đi qua một tệp mbox lớn, phân tích cú pháp email. Tôi có thể làm điều đó với:Phân tích cú pháp các tệp mbox bằng Python

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]) 

Nhưng tôi cần kiểm soát nhiều hơn. Tôi cần để có thể có được vị trí byte của sự khởi đầu của một email nhất định trong tập tin mbox và tôi cũng cần phải nhận được số byte trong tin nhắn (như được đại diện trên đĩa). Và sau đó trong tương lai, thay vì lặp lại từ đầu tệp mbox, tôi cần có khả năng tìm kiếm một thông điệp cụ thể và chỉ phân tích cú pháp đó (do đó một trong những nhu cầu nhận vị trí byte trên đĩa). Đây là những tập tin mbox lớn và hiệu quả là một mối quan tâm.

Mục đích của tất cả điều này là để tôi có thể tạo tệp tóm tắt, chứa một số bit nhỏ về mỗi email trong mbox và sau đó trong tương lai, hãy tra cứu từng email trong mbox một cách hiệu quả.

+0

Tôi chưa bao giờ sử dụng 'hộp thư', nhưng tôi chỉ đọc 'help (mailbox.mbox)'. Bạn không thể sử dụng phương thức '.iterkeys()' để nhận một vòng lặp của các giá trị khóa, và sau đó sử dụng các giá trị khóa để tìm các thông điệp? Tại sao bạn muốn sử dụng chỉ mục byte làm khóa để tìm thư thay vì sử dụng mô-đun ... bạn đã thử sử dụng mô đun để lập chỉ mục thư theo khóa chưa? Nếu bạn đã thử nó và nó quá chậm hoặc một cái gì đó, xin vui lòng nói như vậy. – steveha

+0

Giả sử tôi có mbox 10.000 email. Tôi không muốn phải đọc/phân tích/lặp lại trên 9,998 người trong số họ khi tôi chỉ muốn email cuối cùng. Tôi muốn tìm đến điểm đó trong tệp mbox và chỉ đọc tin nhắn đó. –

+0

@MarkFletcher Bạn có làm việc này không? Nếu vậy, xin vui lòng cho tôi biết. – kingmakerking

Trả lời

8

Tôi chưa thử nghiệm điều này, nhưng một cái gì đó như thế này có thể làm việc cho bạn. Chỉ cần mở tập tin (ở chế độ nhị phân sao cho số byte của bạn là chính xác), và quét qua nó, tìm tin nhắn.

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)) 

Một khi bạn có chỉ mục, bạn có thể sử dụng phương pháp .seek() trên một đối tượng tập tin để tìm kiếm ở đó, và .read(length) trên đối tượng tập tin để đọc chỉ là một tin nhắn. Tôi không chắc chắn làm thế nào bạn sẽ sử dụng mô-đun mailbox với một chuỗi, mặc dù; Tôi nghĩ rằng nó có nghĩa là để làm việc trên một hộp thư tại chỗ. Có thể có một số mô-đun phân tích thư khác mà bạn có thể sử dụng.

+1

Ok, cảm ơn. Tôi đoán tôi sẽ sử dụng một cái gì đó như chiến lược này. btw, sự bắt đầu của một email trong một mbox bắt đầu với 'From' (không có :). Tôi có thể sử dụng email.Parser để phân tích cú pháp email. Cảm ơn. –

+0

Tôi sẽ chỉnh sửa câu trả lời để đưa ra ':'. Tôi đã làm * nói rằng tôi đã không kiểm tra nó ... Chúc may mắn với dự án của bạn, và có một ngày cuối tuần tuyệt vời! – steveha

+0

Đối với những gì nó có giá trị, cho người dùng trong tương lai, nó thực sự là cả hai, ít nhất là trên phiên bản mới nhất của OSX. def is_mail_start (dòng): \t return line.startswith ("From") và không line.startswith ("From:") – adammenges

Các vấn đề liên quan