2

Gmailサーバーからメールを取得するためのPythonコードをいくつか作成しました。以下のコードは次のとおりです。

self.M = imaplib.IMAP4_SSL(self.IMAP_SERVER, self.IMAP_PORT)
data = self.M.fetch(id,"(RFC822)")
if data[0] == 'OK':
    msg = email.message_from_string(data[1][0][1])
else:
    print 'Error!'
mail_subject = email.Header.decode_header(msg['subject'])[0][0]
print email.Header.decode_header(msg['subject'])
print '~~~separator~~~'
print mail_subject

英語のメールの件名が正しく表示されます:

[('[bonnshore.github.com] Page build successful', None)]

~~~separator~~~

[bonnshore.github.com] Page build successful

しかし、代わりに中国語の後:

[('\xd5\xe2\xca\xc7\xd6\xd0\xce\xc4\xb2\xe2\xca\xd4\xa3\xa1', 'gb2312')]

~~~separator~~~

╒Γ╩╟╓╨╬─▓Γ╩╘úí

関数isinstance()は、文字のタイプが'str'であることを示したので、これを解決しようとしました。

print unicode(mail_subject, 'gb2312')

エラーが発生します:

File "C:\Python27\lib\encodings\cp437.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-6:
character maps to <undefined>

また、文字を直接デコードしようとしました。

print mail_subject.decode("gb2312")

そして、私は再び同じエラーを受け取りました!

だから、これを修正する方法は?

どうもありがとう!:)

4

1 に答える 1

1

生のgb2312を非gb2312コンソールに印刷しているため、最初の試行は文字化けとして表示されますdecode_headerジョブの最初の部分を実行します。これは、外観のヘッダーを=?iso-8859-1?q?p=F6stal?=ユーザーに表示できるものに変換することです。同じヘッダーに複数の文字セットを含めることができるため、取得されるのは(raw_datacharset)ペアのリストです。

正しく推測したように、Unicodeコンストラクターを使用して、それらをUnicodeに変換し、次にUTF-8またはニーズに合ったものに変換することになっています。しかし、コードページ437で中国語を表示できないため、2回目の試行は失敗しました。あなたの3番目の問題は、decodeそしてencode働く方向の誤解から来ています。Unicode文字列は、外部エンコーディングに「エンコード」されます。(ただし、それが成功した場合でも、gb2312を端末に印刷する元の文字化けに戻ります。)

結果をテストするには、Unicode文字列を正しく作成して検査するか、正しいエンコーディングでファイルに出力する必要があります。例えば:

>>> x = unicode('\xd5\xe2\xca\xc7\xd6\xd0\xce\xc4\xb2\xe2\xca\xd4\xa3\xa1', 'gb2312')
>>> import unicodedata
>>> map(unicodedata.name, x)  # see if it looks chinese
['CJK UNIFIED IDEOGRAPH-8FD9', 'CJK UNIFIED IDEOGRAPH-662F', 'CJK UNIFIED IDEOGRAPH-4E2D', 'CJK UNIFIED IDEOGRAPH-6587', 'CJK UNIFIED IDEOGRAPH-6D4B', 'CJK UNIFIED IDEOGRAPH-8BD5', 'FULLWIDTH EXCLAMATION MARK']
>>> print x                   # this works for me because I'm in a UTF-8 locale
这是中文测试!

あなたはそれがあなたのために働くことをテストするためにこれをすることができます:

>>> with open('file.txt', 'w') as f:
...   f.write(x.encode('utf-8'))

最後に、最初のアイテムの戻りdecode_header値を取得するには、ヘッダーの値全体を取得するには不十分であることに注意してください。これは、ヘッダーが複数のチャンクに分割される可能性があるためです。チャンクを単一のUnicode文字列に結合する必要があります。これは、make_headerユーティリティ関数とunicodeコンストラクターを組み合わせて行うのが最適です。

subject_header = msg['subject']
subject = unicode(email.header.make_header(email.header.decode_header(subject_header))
# now proceed as before...

make_headerandを呼び出さなければならないのは直感に反しますが、これはPython3で修正されdecode_headerた現在のAPIです。

于 2013-03-20T07:15:34.960 に答える