2009-05-19 6 views
189

Как отправить содержимое HTML в электронном письме с помощью Python? Я могу отправить простой текст.Отправка HTML-адреса электронной почты с использованием Python

+1

Если вы хотите, чтобы отправить HTML с юникодом смотрите здесь: http://stackoverflow.com/questions/36397827/send-html-mail-with-unicode – guettli

+0

Просто большое предупреждение жира , Если вы отправляете письмо не через [ASCII] (http://en.wikipedia.org/wiki/ASCII), используя Python <3.0, подумайте об использовании электронной почты в [Django] (http://en.wikipedia.org/wiki/Django_% 28web_framework% 29). Он корректно завершает строки [UTF-8] (http://en.wikipedia.org/wiki/UTF-8), а также намного проще в использовании. Вы были предупреждены :-) –

ответ

296

От Python v2.7.14 documentation - 18.1.11. email: Examples:

Here’s an example of how to create an HTML message with an alternative plain text version:

#! /usr/bin/python 

import smtplib 

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

# me == my email address 
# you == recipient's email address 
me = "[email protected]" 
you = "[email protected]" 

# Create message container - the correct MIME type is multipart/alternative. 
msg = MIMEMultipart('alternative') 
msg['Subject'] = "Link" 
msg['From'] = me 
msg['To'] = you 

# Create the body of the message (a plain-text and an HTML version). 
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org" 
html = """\ 
<html> 
    <head></head> 
    <body> 
    <p>Hi!<br> 
     How are you?<br> 
     Here is the <a href="http://www.python.org">link</a> you wanted. 
    </p> 
    </body> 
</html> 
""" 

# Record the MIME types of both parts - text/plain and text/html. 
part1 = MIMEText(text, 'plain') 
part2 = MIMEText(html, 'html') 

# Attach parts into message container. 
# According to RFC 2046, the last part of a multipart message, in this case 
# the HTML message, is best and preferred. 
msg.attach(part1) 
msg.attach(part2) 

# Send the message via local SMTP server. 
s = smtplib.SMTP('localhost') 
# sendmail function takes 3 arguments: sender's address, recipient's address 
# and message to send - here it is sent as one string. 
s.sendmail(me, you, msg.as_string()) 
s.quit() 
+0

Можно ли присоединить третью и четвертую части, обе из которых являются вложениями (один ASCII, один двоичный)? Как это сделать? Благодарю. –

+0

Привет, я заметил, что в конце вы 'quit'' '' объект. Что делать, если я хочу отправить несколько сообщений? Должен ли я уходить каждый раз, когда я отправляю сообщение или отправляю все (в цикле for), а затем выходим раз и навсегда? – xpanta

+0

Обязательно прикрепите html последним, так как предпочтительной (показной) частью будет последний. '# В соответствии с RFC 2046, последняя часть многостраничного сообщения, в данном случае # HTML-сообщение является наилучшим и предпочтительным.' Мне жаль, что я не читал это 2 часа назад – dwkd

9

Вот пример кода. Это вдохновило из кода, найденного на сайте Python Cookbook (не может найти точную ссылку)

def createhtmlmail (html, text, subject, fromEmail): 
    """Create a mime-message that will render HTML in popular 
    MUAs, text in better ones""" 
    import MimeWriter 
    import mimetools 
    import cStringIO 

    out = cStringIO.StringIO() # output buffer for our message 
    htmlin = cStringIO.StringIO(html) 
    txtin = cStringIO.StringIO(text) 

    writer = MimeWriter.MimeWriter(out) 
    # 
    # set up some basic headers... we put subject here 
    # because smtplib.sendmail expects it to be in the 
    # message body 
    # 
    writer.addheader("From", fromEmail) 
    writer.addheader("Subject", subject) 
    writer.addheader("MIME-Version", "1.0") 
    # 
    # start the multipart section of the message 
    # multipart/alternative seems to work better 
    # on some MUAs than multipart/mixed 
    # 
    writer.startmultipartbody("alternative") 
    writer.flushheaders() 
    # 
    # the plain text section 
    # 
    subpart = writer.nextpart() 
    subpart.addheader("Content-Transfer-Encoding", "quoted-printable") 
    pout = subpart.startbody("text/plain", [("charset", 'us-ascii')]) 
    mimetools.encode(txtin, pout, 'quoted-printable') 
    txtin.close() 
    # 
    # start the html subpart of the message 
    # 
    subpart = writer.nextpart() 
    subpart.addheader("Content-Transfer-Encoding", "quoted-printable") 
    # 
    # returns us a file-ish object we can write to 
    # 
    pout = subpart.startbody("text/html", [("charset", 'us-ascii')]) 
    mimetools.encode(htmlin, pout, 'quoted-printable') 
    htmlin.close() 
    # 
    # Now that we're done, close our writer and 
    # return the message body 
    # 
    writer.lastpart() 
    msg = out.getvalue() 
    out.close() 
    print msg 
    return msg 

if __name__=="__main__": 
    import smtplib 
    html = 'html version' 
    text = 'TEST VERSION' 
    subject = "BACKUP REPORT" 
    message = createhtmlmail(html, text, subject, 'From Host <[email protected]>') 
    server = smtplib.SMTP("smtp_server_address","smtp_port") 
    server.login('username', 'password') 
    server.sendmail('[email protected]', '[email protected]', message) 
    server.quit() 
+0

FYI; это произошло с http://code.activestate.com/recipes/67083-send-html-mail-from-python/history/1/ –

50

Вы можете попробовать использовать мой mailer модуль.

from mailer import Mailer 
from mailer import Message 

message = Message(From="[email protected]", 
        To="[email protected]") 
message.Subject = "An HTML Email" 
message.Html = """<p>Hi!<br> 
    How are you?<br> 
    Here is the <a href="http://www.python.org">link</a> you wanted.</p>""" 

sender = Mailer('smtp.example.com') 
sender.send(message) 
+0

Вау, это намного проще, чем smtplib. Я думаю, преимущество smtplib в том, что оно поставляется с большинством дистрибутивов Python. Я думаю, вам нужно нажать, чтобы Mailer отправлен в Debian! –

+0

Модуль Mailer отлично работает, но он утверждает, что работает с Gmail, но не работает, и нет документов. – MFB

+1

@MFB - Пробовали ли вы ретрансляцию Bitbucket? https://bitbucket.org/ginstrom/mailer/ –

32

Вот Gmail реализация принятого ответа:

import smtplib 

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

# me == my email address 
# you == recipient's email address 
me = "[email protected]" 
you = "[email protected]" 

# Create message container - the correct MIME type is multipart/alternative. 
msg = MIMEMultipart('alternative') 
msg['Subject'] = "Link" 
msg['From'] = me 
msg['To'] = you 

# Create the body of the message (a plain-text and an HTML version). 
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org" 
html = """\ 
<html> 
    <head></head> 
    <body> 
    <p>Hi!<br> 
     How are you?<br> 
     Here is the <a href="http://www.python.org">link</a> you wanted. 
    </p> 
    </body> 
</html> 
""" 

# Record the MIME types of both parts - text/plain and text/html. 
part1 = MIMEText(text, 'plain') 
part2 = MIMEText(html, 'html') 

# Attach parts into message container. 
# According to RFC 2046, the last part of a multipart message, in this case 
# the HTML message, is best and preferred. 
msg.attach(part1) 
msg.attach(part2) 
# Send the message via local SMTP server. 
mail = smtplib.SMTP('smtp.gmail.com', 587) 

mail.ehlo() 

mail.starttls() 

mail.login('userName', 'password') 
mail.sendmail(me, you, msg.as_string()) 
mail.quit() 
+1

Отличный код, он работает для меня, если я включен [низкая безопасность в google] (https://www.google.com/settings/security/lesssecureapps) – Tovask

+11

Я использую Google [специальный пароль для приложения] (https: //support.google.com/accounts/answer/185833) с python smtplib, сделал трюк, не требуя низкой безопасности. – yoyo

27

Вот простой способ отправить HTML электронной почты, просто указав Content-Type заголовка, как «текст/html»:

import email.message 
import smtplib 

msg = email.message.Message() 
msg['Subject'] = 'foo' 
msg['From'] = '[email protected]' 
msg['To'] = '[email protected]' 
msg.add_header('Content-Type','text/html') 
msg.set_payload('Body of <b>message</b>') 

s = smtplib.SMTP(mailmerge_conf.smtp_server) 
s.starttls() 
s.login(email_login, 
     email_passwd) 
s.sendmail(msg['From'], [msg['To']], msg.as_string()) 
+2

Это приятный простой ответ, удобный для быстрого и грязного сценариев, спасибо. BTW можно ссылаться на принятый ответ для простого примера «smtplib.SMTP()», который не использует tls. Я использовал это для внутреннего скрипта на работе, где мы используем ssmtp и локальный mailhub. Кроме того, в этом примере отсутствует 's.quit()'. –

+0

«mailmerge_conf.smtp_server» не определен ... по крайней мере, это то, что говорит Python 3.6 ... – ZEE

+0

я получил сообщение об ошибке при использовании списков на основе получателей AttributeError: «список» объект не имеет атрибута «lstrip» любого решения? – navotera

2

Фактически, yagmail принял несколько иной подход.

по умолчанию отправьте HTML с автоматическим возвратом для неспособных считывателей электронной почты. Это уже не XVII век.

Конечно, это может быть изменено, но здесь идет:

import yagmail 
yag = yagmail.SMTP("[email protected]", "mypassword") 

html_msg = """<p>Hi!<br> 
       How are you?<br> 
       Here is the <a href="http://www.python.org">link</a> you wanted.</p>""" 

yag.send("[email protected]", "the subject", html_msg) 

Для получения инструкций по установке и многих других больших возможностей, посмотри на github.

0

Вот мой ответ на AWS с помощью boto3

subject = "Hello" 
    html = "<b>Hello Consumer</b>" 

    client = boto3.client('ses', region_name='us-east-1', aws_access_key_id="your_key", 
         aws_secret_access_key="your_secret") 

client.send_email(
    Source='ACME <[email protected]>', 
    Destination={'ToAddresses': [email]}, 
    Message={ 
     'Subject': {'Data': subject}, 
     'Body': { 
      'Html': {'Data': html} 
     } 
    } 
1

Вот рабочий пример для отправки простых текстовых и HTML-письма от Python с использованием smtplib вместе с CC и BCC вариантов.

https://varunver.wordpress.com/2017/01/26/python-smtplib-send-plaintext-and-html-emails/

#!/usr/bin/env python 
import smtplib 
from email.mime.multipart import MIMEMultipart 
from email.mime.text import MIMEText 

def send_mail(params, type_): 
     email_subject = params['email_subject'] 
     email_from = "[email protected]" 
     email_to = params['email_to'] 
     email_cc = params.get('email_cc') 
     email_bcc = params.get('email_bcc') 
     email_body = params['email_body'] 

     msg = MIMEMultipart('alternative') 
     msg['To'] = email_to 
     msg['CC'] = email_cc 
     msg['Subject'] = email_subject 
     mt_html = MIMEText(email_body, type_) 
     msg.attach(mt_html) 

     server = smtplib.SMTP('YOUR_MAIL_SERVER.DOMAIN.COM') 
     server.set_debuglevel(1) 
     toaddrs = [email_to] + [email_cc] + [email_bcc] 
     server.sendmail(email_from, toaddrs, msg.as_string()) 
     server.quit() 

# Calling the mailer functions 
params = { 
    'email_to': '[email protected]', 
    'email_cc': '[email protected]', 
    'email_bcc': '[email protected]', 
    'email_subject': 'Test message from python library', 
    'email_body': '<h1>Hello World</h1>' 
} 
for t in ['plain', 'html']: 
    send_mail(params, t) 
+0

Подумайте, этот ответ охватывает все. Отличная ссылка – stingMantis