Как установить кодировку в электронной почте с помощью smtplib в Python 2.7?

Пишу простой smtp-отправитель с аутентификацией. Вот мой код

    SMTPserver, sender, destination = 'smtp.googlemail.com', '[email protected]', ['[email protected]']
    USERNAME, PASSWORD = "user", "password"

    # typical values for text_subtype are plain, html, xml
    text_subtype = 'plain'


    content="""
    Hello, world!
    """

    subject="Message Subject"

    from smtplib import SMTP_SSL as SMTP       # this invokes the secure SMTP protocol (port 465, uses SSL)
    # from smtplib import SMTP                  # use this for standard SMTP protocol   (port 25, no encryption)
    from email.MIMEText import MIMEText

    try:
        msg = MIMEText(content, text_subtype)
        msg['Subject']=       subject
        msg['From']   = sender # some SMTP servers will do this automatically, not all

        conn = SMTP(SMTPserver)
        conn.set_debuglevel(False)
        conn.login(USERNAME, PASSWORD)
        try:
            conn.sendmail(sender, destination, msg.as_string())
        finally:
            conn.close()

    except Exception, exc:
        sys.exit( "mail failed; %s" % str(exc) ) # give a error message

Работает отлично, пока я не пытаюсь отправить символы не в формате ascii (русская кириллица). Как мне определить кодировку в сообщении, чтобы оно отображалось должным образом? Заранее спасибо!

UPD. Я изменил свой код:

text_subtype = 'text'
content="<p>Текст письма</p>"
msg = MIMEText(content, text_subtype)
msg['From']=sender # some SMTP servers will do this automatically, not all
msg['MIME-Version']="1.0"
msg['Subject']="=?UTF-8?Q?Тема письма?="
msg['Content-Type'] = "text/html; charset=utf-8"
msg['Content-Transfer-Encoding'] = "quoted-printable"
…
conn.sendmail(sender, destination, str(msg))

Итак, в первый раз я указываю text_subtype = 'text', а затем в заголовке помещаю строку msg ['Content-Type'] = "text / html; charset = utf-8". Это правильно?

ОБНОВЛЕНИЕ. Наконец, я решил проблему с сообщениями. Вы должны написать что-нибудь вроде msg = MIMEText (content.encode ('utf-8'), 'plain', 'UTF-8')


person f1nn    schedule 24.04.2012    source источник


Ответы (3)


from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def contains_non_ascii_characters(str):
    return not all(ord(c) < 128 for c in str)   

def add_header(message, header_name, header_value):
    if contains_non_ascii_characters(header_value):
        h = Header(header_value, 'utf-8')
        message[header_name] = h
    else:
        message[header_name] = header_value    
    return message

............
msg = MIMEMultipart('alternative')
msg = add_header(msg, 'Subject', subject)

if contains_non_ascii_characters(html):
    html_text = MIMEText(html.encode('utf-8'), 'html','utf-8')
else:
    html_text = MIMEText(html, 'html')    

if(contains_non_ascii_characters(plain)):
    plain_text = MIMEText(plain.encode('utf-8'),'plain','utf-8') 
else:
    plain_text = MIMEText(plain,'plain')

msg.attach(plain_text)
msg.attach(html_text)

Это должно дать вам правильную кодировку как для текста, так и для заголовков, независимо от того, содержит ли ваш текст символы, отличные от ASCII, или нет. Это также означает, что вы не будете автоматически использовать кодировку base64 без необходимости.

person Lorcan O'Neill    schedule 24.01.2013
comment
Привет, Лоркан! Как насчет «Кому» и «От», если я укажу их в своем сообщении (например, как msg ['From'] = '[email protected]')? Мне тоже надо кодировать или нет? - person Stan Zeez; 24.10.2017

Вы должны закодировать текст сообщения с помощью UTF-8

msg = MIMEText(content.encode('utf-8'), text_subtype).

Подробнее здесь: http://radix.twistedmatrix.com/2010/07/how-to-send-good-unicode-email-with.html

person yablokoff    schedule 24.04.2012
comment
Разве кодировку нельзя также указать в качестве третьего параметра для MIMEText? - person Michael Scheper; 26.10.2015

Возможно, вам придется использовать заголовок SMTP для отправки разных кодировок, попробуйте добавить это -

msg['Content-Type'] = "text/html; charset=us-ascii"

(Измените кодировку в соответствии с вашими потребностями)

person Karthik Ananth    schedule 24.04.2012
comment
Что ж, у меня это сработало - тема отображается правильно, хотя кодировка текста сообщения все еще неточная. - person f1nn; 24.04.2012
comment
Я обновил свой пост. Пожалуйста, не могли бы вы взглянуть на новый - person f1nn; 24.04.2012