Python kullanarak HTML e-posta gönderme


260

Python kullanarak bir e-postadaki HTML içeriğini nasıl gönderebilirim? Basit metin gönderebilirim.


Sadece büyük bir yağ uyarısı. ASCII olmayan bir e-postayı Python <3.0 kullanarak gönderiyorsanız , e-postayı Django'da kullanmayı düşünün . UTF-8 dizelerini doğru bir şekilde sarar ve kullanımı çok daha kolaydır. Uyarıldınız :-)
Anders Rune Jensen

1
Unicode ile bir HTML göndermek istiyorsanız, buraya bakın: stackoverflow.com/questions/36397827/…
guettli

Yanıtlar:


419

Gönderen 18.1.11 - Python v2.7.14 belgelerinde. e-posta: Örnekler :

Alternatif düz metin sürümüne sahip bir HTML mesajının nasıl oluşturulacağına ilişkin bir örnek:

#! /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 = "my@email.com"
you = "your@email.com"

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

1
Her ikisi de ek olan (bir ASCII, bir ikili) üçüncü ve dördüncü bir parça eklemek mümkün mü? Bunu nasıl yaparsınız? Teşekkürler.
Hamish Grubijan

1
Merhaba, sonunda sen de fark nesne. Birden fazla mesaj göndermek istersem ne olur? İletiyi her gönderdiğimde veya hepsini (bir for döngüsü içinde) gönderdiğimde ve sonra bir kez ve herkes için çıkmalı mıyım? quits
xpanta

Html'yi en son eklediğinizden emin olun, çünkü tercih edilen (gösterilen) kısım en son eklenen kısım olacaktır. # According to RFC 2046, the last part of a multipart message, in this case # the HTML message, is best and preferred. Keşke bu 2 saat önce okumak
dwkd

1
Uyarı: Metinde ascii olmayan karakterler varsa bu başarısız olur.
guettli

2
Hmm, msg.as_string () için hatayı alıyorum: liste nesnesinin hiçbir öznitelik kodlaması yok
JohnAndrews

61

Posta modülümü kullanmayı deneyebilirsiniz .

from mailer import Mailer
from mailer import Message

message = Message(From="me@example.com",
                  To="you@example.com")
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)

Mailer modülü harika, ancak Gmail ile çalıştığını iddia ediyor, ancak çalışmıyor ve hiçbir doküman yok.
MFB

1
Bitbucket deposunu denediniz mi? bitbucket.org/ginstrom/mailer
Ryan Ginstrom

2
Gmail biri sağlamalıdır için use_tls=True, usr='email've pwd='password'başlatırken Mailerve işe yarayacak.
ToonAlfrink

message.Body = """Some text to show when the client cannot show HTML emails"""
Kodunuza iletiden

büyük ama değişken değerlerini bağlantıya nasıl ekleyeceğim yani böyle bir bağlantı oluşturmak demek <a href=" python.org/somevalues"> bağlantı </ a > Böylece bu değerlere gittiği yollardan erişebiliyorum. Teşekkürler
TaraGurung

49

Kabul edilen cevabın Gmail uygulaması:

import smtplib

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

# me == my email address
# you == recipient's email address
me = "my@email.com"
you = "your@email.com"

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


15
Ben python smtplib ile bir google uygulama özel şifre kullanın, düşük güvenlik gitmeden hile yaptı.
yoyo

2
yukarıdaki yorumları okuyan herkes için: "Gmail şifrenizde daha önce 2 adımlı doğrulamayı etkinleştirdiyseniz" Uygulama Şifresi "gerekir.
Mugen

İletinin HTML bölümüne bir şey dinamik olarak eklemenin bir yolu var mı?
magma

40

İçerik Türü başlığını 'metin / html' olarak belirterek HTML e-postası göndermenin basit bir yolu:

import email.message
import smtplib

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

# Send the message via local SMTP server.
s = smtplib.SMTP('localhost')
s.starttls()
s.login(email_login,
        email_passwd)
s.sendmail(msg['From'], [msg['To']], msg.as_string())
s.quit()

2
Bu güzel ve basit bir cevap, hızlı ve kirli komut dosyaları için kullanışlı, teşekkürler. BTW smtplib.SMTP(), tls kullanmayan basit bir örnek için kabul edilen cevaba başvurabilir . Bunu ssmtp ve yerel bir mailhub kullandığımız bir dahili script için kullandım. Ayrıca, bu örnek eksik s.quit().
Mike S

1
"mailmerge_conf.smtp_server" tanımlı değil ... en azından Python
3.6'nın

liste tabanlı alıcıları kullanırken hata aldım AttributeError: 'list' nesnesi 'lstrip' özniteliği herhangi bir çözüm var mı?
navotera

10

İşte örnek kod. Bu, Python Yemek Tarifleri sitesinde bulunan koddan esinlenmiştir (tam bağlantı bulunamıyor)

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 <sender@host.com>')
    server = smtplib.SMTP("smtp_server_address","smtp_port")
    server.login('username', 'password')
    server.sendmail('sender@host.com', 'target@otherhost.com', message)
    server.quit()


5

python3 için @ taltman'ın cevabını geliştirin :

  • e-posta oluşturmak email.message.EmailMessageyerine kullanın email.message.Message.
  • email.set_contentfunc kullanın , subtype='html'argüman atayın . yerine düşük seviyeli işlev set_payloadve başlığı el ile ekleyin.
  • e-posta göndermek için SMTP.send_messagefunc yerine SMTP.sendmailfunc kullanın.
  • withbağlantıyı otomatik kapatmak için bloğu kullanın.
from email.message import EmailMessage
from smtplib import SMTP

# construct email
email = EmailMessage()
email['Subject'] = 'foo'
email['From'] = 'sender@test.com'
email['To'] = 'recipient@test.com'
email.set_content('<font color="red">red color text</font>', subtype='html')

# Send the message via local SMTP server.
with smtplib.SMTP('localhost') as s:
    s.login('foo_user', 'bar_password')
    s.send_message(email)

4

Aslında yagmail biraz farklı bir yaklaşım izledi .

Öyle olacak varsayılan tarafından aciz eposta-okuyucular için otomatik yedek kullanımıyla gönderme HTML,. Artık 17. yüzyıl değil.

Tabii ki, geçersiz kılınabilir, ancak işte gidiyor:

import yagmail
yag = yagmail.SMTP("me@example.com", "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("to@example.com", "the subject", html_msg)

Kurulum talimatları ve daha birçok harika özellik için github'a bir göz atın .


3

smtplibCC ve BCC seçenekleriyle birlikte Python'dan düz metin ve HTML e-postaları göndermek için çalışan bir örnek .

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 = "from_email@domain.com"
      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': 'to_email@domain.com',
    'email_cc': 'cc_email@domain.com',
    'email_bcc': 'bcc_email@domain.com',
    'email_subject': 'Test message from python library',
    'email_body': '<h1>Hello World</h1>'
}
for t in ['plain', 'html']:
    send_mail(params, t)

Bu cevabın her şeyi kapsadığını düşünün. Büyük bağlantı
stingMantis

1

İşte boto3 kullanarak AWS için cevabım

    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 <do-not-reply@acme.com>',
    Destination={'ToAddresses': [email]},
    Message={
        'Subject': {'Data': subject},
        'Body': {
            'Html': {'Data': html}
        }
    }

0

Office 365'te Kuruluş hesabından e-posta göndermek için en basit çözüm:

from O365 import Message

html_template =     """ 
            <html>
            <head>
                <title></title>
            </head>
            <body>
                    {}
            </body>
            </html>
        """

final_html_data = html_template.format(df.to_html(index=False))

o365_auth = ('sender_username@company_email.com','Password')
m = Message(auth=o365_auth)
m.setRecipients('receiver_username@company_email.com')
m.setSubject('Weekly report')
m.setBodyHTML(final_html_data)
m.sendMessage()

burada df , html_template'e enjekte edilen html Tablosuna dönüştürülen bir veri çerçevesidir.


Soru, Office'i veya bir kurumsal hesabı kullanma hakkında hiçbir şeyden bahsetmiyor. İyi katkı ama asker için çok yararlı değil
Mwikala Kangwa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.