2009-09-15 4 views
8

У меня проблема отправки по электронной почте Юникода с использованием smtplib в Python 3. Это терпит неудачу в 3.1.1, но работает в 2.5.4:Python 3 smtplib отправить с Юникодом

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

ответ

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 требуется байтовая строка, а не Юникод (это то, что указывает протокол SMTP); посмотрите на то, что msg.as_string() выглядит как для каждого из двух способов его создания - учитывая «отсутствие угадывания или кодирования», ваш путь по-прежнему имеет этот символ евро (и никак не для sendmail, чтобы превратить его в байтовую строку), мой (и utf-8 четко указывается повсюду).

+0

Это отправляется без генерации сообщения об ошибке. Я отправил в Thunderbird и gmail. Thunderbird только показывал 10 в качестве текста сообщения. Gmail показал полный 10 евро. Python отправляет как «кодирование контента: base64», в то время как Thunderbird отправляет € 10 в качестве «кодирования контента: 8-бит» и gmail отправляет как «multipart/alternative»; border = ... 'Любые предложения для генерации сообщения, которое Thunderbird может интерпретировать? – foosion

+0

Я не эксперт Thunderbird, но попробую другие кодировки, такие как 'iso-8859-15'. Хотя любая программа в эти дни, которая не может делать utf-8, действительно стоит забросить в мусорную корзину истории, ум! -) –

+0

Проблема не в том, чтобы быть iso-8859-15 или utf-8, кажется, Content-Transfer-Encoding. Все остальное, что я проверил, использует 8-бит, в то время как python использует base64. Принуждение заголовка к 8-битовому не помогает. Использование quopri.encodestring() может работать для получения 8-битной кодировки, но я не смог понять, как заставить ее работать. – foosion

2

_charset параметр MIMEText по умолчанию us-ascii согласно docs. Начиная с нет от нас-ascii set он не работает.

пример в документации, что вы пытались четко сказано:

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

Вы можете использовать .get_charset метод вашего сообщения исследовать кодовую, там кстати .set_charset также.

+0

Как вы говорите, кодировка - это us-ascii, которая не включает €. Использование set_charset в msg не устраняет проблему. Проблема (я должен быть более точной) находится на линии sendmail - UnicodeEncodeError: кодек ascii не может кодировать символ '\ x80' в позиции 161: порядковый номер не в диапазоне (128). Я читал это, чтобы иметь в виду, что у меня есть для кодирования текста, чтобы все было в диапазоне (128), но я не смог понять, как это сделать. – foosion

+0

Я смотрел третий пример на странице примеров, отправляя весь каталог. Я попытался отправить каталог, состоящий из одного zip-файла, используя пример. Это не удалось. – foosion

 Смежные вопросы

  • Нет связанных вопросов^_^