Python 3 smtplib отправить с символами Юникода
У меня проблема с отправкой по электронной почте символов Unicode с помощью smtplib в Python 3. Это не удается в 3.1.1, но работает в 2.5.4:
import smtplib
from email.mime.text import MIMEText
sender = to = 'ABC@DEF.com'
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
Какие-либо предложения?
3 ответа
Ключ находится в документах:
class email.mime.text.MIMEText(_text, _subtype='plain', _charset='us-ascii')
Подкласс MIMENonMultipart, класс MIMEText используется для создания объектов MIME текста основного типа. _text - это строка для полезной нагрузки. _subtype является второстепенным типом и по умолчанию равняется простому. _charset является набором символов текста и передается в качестве параметра конструктору MIMENonMultipart; это по умолчанию для нас-ascii. Нет угадывания или кодирования не выполняется на текстовых данных.
Итак, что вам нужно, это ясно, а не msg = MIMEText('€10')
, скорее:
msg = MIMEText('€10'.encode('utf-8'), _charset='utf-8')
Хотя не все это четко задокументировано, sendmail нужна строка байтов, а не Unicode (это то, что определяет протокол SMTP); посмотрите на что msg.as_string()
Похоже, для каждого из двух способов его построения - учитывая "не угадывать и не кодировать", ваш путь все еще имеет этот символ евро (и у sendmail нет способа превратить его в строку байтов), мой нет (и utf-8 четко указан везде).
_charset
параметр MIMEText
по умолчанию us-ascii
в соответствии с документами. поскольку €
это не от нас-ascii set это не работает.
Например, в документах, которые вы пробовали, четко сказано:
Для этого примера предположим, что текстовый файл содержит только символы ASCII.
Вы могли бы использовать .get_charset
метод по вашему сообщению исследовать кодировку, там кстати .set_charset
также.
У Гаса Мюллера была похожая проблема: http://bugs.python.org/issue4403