2009-09-15 36 views
8

我有在Python 3這失敗3.1.1電子郵件的smtplib使用Unicode字符的問題,但在2.5.4的工作原理:的Python 3用的smtplib Unicode字符發送

import smtplib 
    from email.mime.text import MIMEText 

    sender = to = '[email protected]' 
    server = 'smtp.DEF.com' 
    msg = MIMEText('€10') 
    msg['Subject'] = 'Hello' 
    msg['From'] = sender 
    msg['To'] = to 
    s = smtplib.SMTP(server) 
    s.sendmail(sender, [to], msg.as_string()) 
    s.quit() 

我試過一個例子從文檔,也失敗了。 http://docs.python.org/3.1/library/email-examples.html,將目錄的內容作爲MIME郵件發送示例

有什麼建議嗎?

+0

爲了澄清,在2.5.4,它發送沒有錯誤消息,但取代「€」與「?」。 – foosion 2009-09-15 21:17:27

回答

10

的關鍵是the docs

class email.mime.text.MIMEText(_text, _subtype='plain', _charset='us-ascii') 

A subclass of MIMENonMultipart, the MIMEText class is used to create MIME objects of major type text. _text is the string for the payload. _subtype is the minor type and defaults to plain. _charset is the character set of the text and is passed as a parameter to the MIMENonMultipart constructor; it defaults to us-ascii. No guessing or encoding is performed on the text data.

所以,你需要的是清晰,msg = MIMEText('€10'),而是:

msg = MIMEText('€10'.encode('utf-8'), _charset='utf-8') 

雖然不是所有的明確記載,sendmail需要一個字節字符串,而不是一個Unicode字符串(這是SMTP協議指定的);看看msg.as_string()對於構建它的兩種方式是什麼樣的 - 給定「不猜測或編碼」,你的方式仍然有歐元字符(並且沒有辦法讓sendmail把它變成字節串),我的沒有(並且utf-8在整個過程中都有明確的說明)。

+0

發送時不生成錯誤消息。我發送到Thunderbird和Gmail。雷鳥只顯示了10條消息的文本。 Gmail顯示全額€10。 Python作爲'content-transfer-encoding:base64'發送,而Thunderbird發送€10作爲'content-transfer-encoding:8-bit',gmail作爲'multipart/alternative發送; boundary = ...'任何有關生成Thunderbird可以解釋的消息的建議? – foosion 2009-09-16 02:38:33

+0

我不是雷鳥專家,但可以嘗試其他編碼,例如'iso-8859-15'。雖然現在任何不能做utf-8的程序都值得投入到歷史的垃圾箱當中 - ) – 2009-09-16 04:17:04

+0

這個問題似乎並不是iso-8859-15或utf-8,它似乎是傳送編碼的內容。我檢查的其他東西都使用8位,而python使用base64。將標題強制轉換爲8位不會有幫助。使用quopri.encodestring()可能會獲得8位編碼,但我一直無法弄清楚如何使它工作。 – foosion 2009-09-16 11:37:46

2

_charset參數MIMEText默認爲us-ascii根據docs。由於不是來自us-ascii集,它不起作用。在你已經清楚地嘗試過的文檔

例如規定:

For this example, assume that the text file contains only ASCII characters.

您可以使用您的信息.get_charset方法進行調查的字符集,也順便.set_charset爲好。

+0

正如你所說,charset是us-ascii,它不包括€。在msg上使用set_charset不能解決問題。這個問題(我應該更加確切)在sendmail行 - UnicodeEncodeError:'ascii'編解碼器不能在位置161編碼字符'\ x80':序號不在範圍內(128)我讀這意味着我有對文本進行編碼以使所有內容都在範圍內(128),但我一直無法弄清楚如何進行。 – foosion 2009-09-15 20:52:49

+0

我正在查看示例頁面上的第三個示例,發送整個目錄。我試着用這個例子發送一個包含一個zip文件的目錄。這失敗了。 – foosion 2009-09-15 20:53:42