2009-02-27 26 views
7

Ứng dụng của tôi được viết bằng python. Những gì tôi đang làm là tôi đang chạy một kịch bản trên mỗi email nhận được bởi postfix và làm một cái gì đó với nội dung email. Procmail chịu trách nhiệm chạy tập lệnh lấy email làm đầu vào. Vấn đề bắt đầu khi tôi đang chuyển đổi thông điệp đầu vào (có thể là văn bản) thành đối tượng email_message (vì sau này có ích). Tôi đang sử dụng email.message_from_string (trong đó email là mô-đun email mặc định, đi kèm với python).Cơ thể email đôi khi là một chuỗi và một danh sách. Tại sao?

import email message = email.message_from_string(original_mail_content) message_body = message.get_payload()

MESSAGE_BODY này đôi khi được trả về một danh sách [dụ email.message.Message, email.message.Message dụ] và đôi khi trả về một chuỗi (nội dung cơ thể thực tế của các email gửi đến). Tại sao lại như vậy. Và thậm chí tôi còn tìm thấy một quan sát nữa. Khi tôi duyệt qua email.message.Message.get_payload() docstring, tôi thấy điều này ..
"" " Tải trọng sẽ là đối tượng danh sách hoặc chuỗi. Nếu bạn tắt đối tượng danh sách, bạn sửa đổi tải trọng của tin nhắn tại chỗ ..... "" "

Vậy làm thế nào để tôi có phương pháp chung để có được nội dung email thông qua python? Hãy giúp tôi ra.

Trả lời

11

Vâng, câu trả lời là chính xác, bạn nên đọc các tài liệu, nhưng đối với một ví dụ về một cách chung chung:

def get_first_text_part(msg): 
    maintype = msg.get_content_maintype() 
    if maintype == 'multipart': 
     for part in msg.get_payload(): 
      if part.get_content_maintype() == 'text': 
       return part.get_payload() 
    elif maintype == 'text': 
     return msg.get_payload() 

này là dễ bị một số thảm họa, vì nó là có thể tưởng tượng những phần thân thể có multiparts và nó thực sự chỉ trả về phần văn bản đầu tiên, vì vậy điều này cũng có thể sai, nhưng bạn có thể chơi với nó.

+0

Trong danh sách thư tôi đã nói, tôi đã thử chạy get_payload() trên mỗi đối tượng. Cả hai trở lại cùng một điều. Là một loại đối tượng của bản sao của người khác, để nếu tôi nhận được get_payload được gọi là trên một phần duy nhất sẽ làm gì ??? –

+0

Phụ thuộc vào những gì bạn đã được gửi. Ví dụ: bạn có thể nhận được văn bản/html và văn bản/phiên bản thuần túy của cùng một điều. Bạn có thể sửa đổi chức năng để tìm và thích loại văn bản/nội dung đơn giản hơn các loại/văn bản khác. – bobince

+0

Bobince tuyệt vời.Bạn hoàn toàn đúng: D –

10

Như điên như nó có vẻ, lý do cho đôi khi chuỗi, đôi khi danh sách-ngữ nghĩa là given in the documentation. Về cơ bản, các thông điệp nhiều phần được trả về dưới dạng danh sách.

+0

Đó. Là. Khùng. –

9

Thay vì chỉ đơn giản là tìm kiếm một phần phụ, sử dụng đi bộ() để lặp qua các nội dung tin nhắn

def walkMsg(msg): 
    for part in msg.walk(): 
    if part.get_content_type() == "multipart/alternative": 
     continue 
    yield part.get_payload(decode=1) 

Việc đi bộ() phương thức trả về một iterator mà bạn có thể lặp với (tức là nó là một máy phát điện) . Nếu thông báo không phải là một vùng chứa các phần (nghĩa là không có tệp đính kèm hoặc thay thế), thì phương thức walk() sau đó sẽ trả về một trình lặp với một phần tử duy nhất - chính thông báo đó.

Bạn muốn bỏ qua bất kỳ phần 'multipart' nào vì chúng chỉ là keo.

Phương thức trên trả về tất cả các phần có thể đọc được. Bạn có thể muốn mở rộng điều này để chỉ cần trả lại các phần văn bản nếu chúng chứa thông tin bạn đang tìm kiếm.

Lưu ý rằng tính Python 2.5, phương pháp get_type(), get_main_type(), và get_subtype() đã được gỡ bỏ ->http://docs.python.org/library/email.message.html#email.message.Message.walk

+0

Đây là câu trả lời tốt hơn nhiều so với câu trả lời được OP, IMHO chấp nhận. –

+0

Tôi nghĩ rằng đơn '=' phải là '==' trong câu lệnh if – veered

+0

Cảm ơn - đã sửa – timbo

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