2014-09-16 3 views
3

Я использую модули Python imaplib и электронной почты, чтобы получить список писем от smtp и сделать с ними что-то с ними позже. Это фрагмент кода я использую, чтобы захватить и декодировать сообщения электронной почты:Письма, отправленные с мобильных устройств, странно декодируются с использованием электронной почты lib

import imaplib 
import email 

# Connect to server 
box = imaplib.IMAP4(CSMTP_SERVER) 
box.login(CSMTP_USERNAME, CSMTP_PASSWORD) 

# List inbox 
box.select('INBOX') 

# Retrieve email list ID's matching search patterns 
# Return from search is this: 
# ('OK', ['1 2 3 4 5 6 7 8 9 10 11 12 13 14']) 
data = box.search(None, 'ALL')[1] 
for num in data[0].split(): 

# Retrieve message headers and body 
headers = email.message_from_string(box.fetch(num, '(RFC822)')[1][0][1]) 
body = headers.get_payload() 
if not isinstance(body, str): 
    body = headers.get_payload()[0].get_payload() 

print headers, body 

Это работает как шарм, когда электронная почта отправляется из Hotmail или Gmail, но всякий раз, когда отправляется сообщение электронной почты, например, с Android по умолчанию почтовый APP сообщение будет выглядеть так:

=?utf-8?B?RndkOiBDYXBzaGFyZTogaW1wb3J0aW5nIGZyb20gUGhvdG9z? 
U2VudCBmcm9tIG15IEhUQwoKLS0tLS0gRm9yd2FyZGVkIG1lc3NhZ2UgLS0tLS0KRnJvbTogIkFs 
ZXhhbmRlciBBdnRhbnNraSIgPGFsZXhAYXZ0YW5za2kuY29tPgpUbzogIlBlam1hbiBNYWtoZmki 
IDxwakBtYWtoZmkuY29tPgpTdWJqZWN0OiBDYXBzaGFyZTogaW1wb3J0aW5nIGZyb20gUGhvdG9z 
CkRhdGU6IFdlZCwgU2VwIDEwLCAyMDE0IDk6MDYgUE0KCkhpIFBlam1hbiwKCkkgd2FzIHBsYXlp 
bmcgd2l0aCBDYXBzaGFyZSB0b2RheSBhbmQgZm91bmQgc29tZXRoaW5nIG1pc3NpbmcuIEkgZ3Vl 
c3MgeW91CmhhdmUgcGxhbnMgZm9yIGl0LCBidXQgaXQgZG9lc24ndCBodXJ0IHRvIG1lbnRpb24g 
aXQsIGp1c3Qgb24gY2FzZS4uLgoKV2hlbiBpbXBvcnRpbmcgcGhvdG9zLCBJIGhhdmUgdGhlIG9w 
dGlvbiB0byBlaXRoZXIgZ2V0IG9uZSBvZiB0aGUgaW1hZ2VzCnRoYXQgYXJlIGRvd25sb2FkZWQg 
b24gbXkgcGhvbmUsIG9yIHRvIHRha2UgYSBuZXcgcGljdHVyZS92aWRlby4gV2hhdCdzCm1pc3Np 
bmcgaXMgYWJpbGl0eSB0byBnZXQgcGhvdG9zIGZyb20gbXkwcyBJJ3ZlIHVzZWQgZG9uJ3Qg 
Y2FyZSB3aGVyZSB0aGUgcGhvdG8gaXMgbG9jYXRlZCBhbmQgYWxsCnBpY3R1cmVzIGFyZSBlcXVh 
bGx5IGFjY2Vzc2libGUgKG9yIG1heWJlIHRoaXMgYXBwbGllcyBvbmx5IHRvIEdvb2dsZQphcHBz 
PykuCgpOb3QgaW1wb3J0YW50LCBubyBpZGVhIGlmIGl0IGlzIGp1c3QgYSBsaW5lIG9yIHR3byBm 
aXggb3Igc29tZXRoaW5nIG1vcmUKY29tcGxpY2F0ZWQuCgpUYWtlIGNhcmUsCgotIEFsZXgsIGJl 
dGEgdGVzdGVyLCBRQSB2b2x1bnRlZXIsIGFuZCBzZW5pb3IgcGVza3kgc3RpY2tsZXI= 

Когда я получил это сообщение, я отправил электронное письмо с мобильного устройства. Я сомневаюсь, что это что-то нужно сделать, больше похоже на то, что некоторые почтовые клиенты не правильно строят заголовки писем на основе RFC822, но мне нужно как-то исправить это и получить возможность получать каждое электронное письмо.

Буду признателен за то, как с этим справиться. Заранее спасибо.

+1

Вы должны проверять 'Content-type' и' заголовки Content-Transfer-Encoding' – goncalopp

+1

Кроме того, стоит отметить, что это [MIME ] (https://en.wikipedia.org/wiki/MIME) и не указывается на базе rfc822. Вы должны читать RFCs 2045-2047 – goncalopp

+0

Я вижу, Не знал об этих заголовках. Спасибо за информацию! –

ответ

2

Это MIME сообщение - это не указано на RFC822, а на новый 2045-2047.

Подавляющее большинство современных электронных писем использует MIME в некотором роде, поэтому вы обязательно должны его поддерживать.

Особое значение для этого сообщения имеет RFC2047, в котором указывается Encoded-Word. Существует good overview on wikipedia, который я частично расшифрую:

Форма: "=? Кодировка кодировки? Кодированный текст? =".

Кодирование может быть «Q», обозначающим Q-кодирование, аналогичное кодировке с кавычками, или «B», обозначающее кодировку base64.

Таким образом, для данного конкретного сообщения, вы должны кодировкой Base64 (B) utf-8 закодированный текст с. Фактическое сообщение начинается сразу после B? и не на второй строке.

Вот несколько простых питон код для обработки все это:

if body.startswith("=?"): 
    i1= body.index("?") 
    i2= body.index("?", i1+1) 
    i3= i2+2 
    encoding= body[i1+1:i2] 
    assert body[i2:i3]=="?B" #don't handle Q format, it's not commonly used 
    body= base64.b64decode(body[i3+1:]).decode(encoding) 
+0

Спасибо, что это было очень полезно. Я проверю MIME и сменил код python ur с некоторым тестированием. –

1

Странная кодирование base64

>>> import base64 
>>> base64.decodestring('RndkOiBDYXBzaGFyZTogaW1wb3J0aW5nIGZyb20gUGhvdG9z?').decode('utf8') 
u'Fwd: Capshare: importing from Photos' 
>>> base64.decodestring('''U2VudCBmcm9tIG15IEhUQwoKLS0tLS0gRm9yd2FyZGVkIG1lc3NhZ2UgLS0tLS0KRnJvbTogIkFs 
... ZXhhbmRlciBBdnRhbnNraSIgPGFsZXhAYXZ0YW5za2kuY29tPgpUbzogIlBlam1hbiBNYWtoZmki 
... IDxwakBtYWtoZmkuY29tPgpTdWJqZWN0OiBDYXBzaGFyZTogaW1wb3J0aW5nIGZyb20gUGhvdG9z 
... CkRhdGU6IFdlZCwgU2VwIDEwLCAyMDE0IDk6MDYgUE0KCkhpIFBlam1hbiwKCkkgd2FzIHBsYXlp 
... bmcgd2l0aCBDYXBzaGFyZSB0b2RheSBhbmQgZm91bmQgc29tZXRoaW5nIG1pc3NpbmcuIEkgZ3Vl 
... c3MgeW91CmhhdmUgcGxhbnMgZm9yIGl0LCBidXQgaXQgZG9lc24ndCBodXJ0IHRvIG1lbnRpb24g 
... aXQsIGp1c3Qgb24gY2FzZS4uLgoKV2hlbiBpbXBvcnRpbmcgcGhvdG9zLCBJIGhhdmUgdGhlIG9w 
... dGlvbiB0byBlaXRoZXIgZ2V0IG9uZSBvZiB0aGUgaW1hZ2VzCnRoYXQgYXJlIGRvd25sb2FkZWQg 
... b24gbXkgcGhvbmUsIG9yIHRvIHRha2UgYSBuZXcgcGljdHVyZS92aWRlby4gV2hhdCdzCm1pc3Np 
... bmcgaXMgYWJpbGl0eSB0byBnZXQgcGhvdG9zIGZyb20gbXkgYWxidW1zIG9yIGJhY2tlZC11cCBw 
... aG90b3MgdGhhdAphcmUgbm90IHBoeXNpY2FsbHkgc3RvcmVkIG9uIHRoZSBkZXZpY2UgLSBmb3Ig 
... ZXhhbXBsZSB0aG9zZSBvbiBHb29nbGUKZHJpdmUuIE1vcbmQgYWxsCnBpY3R1cmVzIGFyZSBlcXVh 
... bGx5IGFjY2Vzc2libGUgKG9yIG1heWJlIHRoaXMgYXBwbGllcyBvbmx5IHRvIEdvb2dsZQphcHBz 
... PykuCgpOb3QgaW1wb3J0YW50LCBubyBpZGVhIGlmIGl0IGlzIGp1c3QgYSBsaW5lIG9yIHR3byBm 
... aXggb3Igc29tZXRoaW5nIG1vcmUKY29tcGxpY2F0ZWQuCgpUYWtlIGNhcmUsCgotIEFsZXgsIGJl 
... dGEgdGVzdGVyLCBRQSB2b2x1bnRlZXIsIGFuZCBzZW5pb3IgcGVza3kgc3RpY2tsZXI=''').decode('utf8') 
u'Sent from my HTC\n\n----- Forwarded message -----\n.... 
+1

может стоить 'decode ('utf-8')' слишком – goncalopp

+0

Я вижу так его base64. Проверяйте его, а также проверьте тип MIME, как было предложено ранее. Спасибо за ответ! –