2012-04-24 4 views
12

Ich schreibe einen einfachen SMTP-Sender mit Authentifizierung. Hier ist mein CodeWie setze ich in Python 2.7 einen Zeichensatz in E-Mails mit smtplib?

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 

Es funktioniert perfekt, bis ich versuche, nicht-ASCII-Zeichen (russisch kyrillisch) zu senden. Wie soll ich einen Zeichensatz in einer Nachricht definieren, damit er richtig angezeigt wird? Danke im Voraus!

UPD. Ich habe meinen Code geändert:

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)) 

Also, erstes Mal, dass ich text_subtype = 'text' spectify, und dann in dem Kopf platziere ich eine msg [ 'Content-Type'] = „text/html; charset = utf -8 "Schnur. Ist es richtig?

UPDATE Schließlich habe ich meine Botschaft Problem gelöst Sie sollten smth wie msg = Mime (content.encode ('utf-8'), 'Ebene', 'UTF-8') schreiben

Antwort

19
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) 

Dies sollten Sie Ihre richtige Codierung geben sowohl für Text und Header unabhängig davon, ob Ihr Text enthält Nicht-ASCII: sollten Sie Ihre Nachricht-Text mit UTF-8

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

Mehr hier kodieren Zeichen oder nicht. Es bedeutet auch, dass Sie die base64-Codierung nicht automatisch unnötig verwenden.

+0

Hallo Lorcan! Wie wäre es mit "An" und "Von", wenn ich sie in meiner msg angeben würde (wie zB msg ['From'] = '[email protected]')? Ich sollte es auch verschlüsseln oder nicht? –

1

Sie müssen SMTP-Header verwenden, können unterschiedliche charsets zu erreichen senden, versuchen Sie, diese -

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

(die charset ändern nach Ihrem Bedarf)

+0

Nun, das hat für mich funktioniert - Thema wird in angemessener Weise gezeigt, obwohl die Codierung des Nachrichtentextes immer noch nicht korrekt ist. – f1nn

+0

Ich habe meinen Beitrag aktualisiert. Könnten Sie sich bitte einen neuen anschauen? – f1nn