Question

Je veux écrire un programme qui envoie un courrier électronique en utilisant Python smtplib . Je cherchai dans le document et les RFCs, mais n'a pas pu trouver tout ce qui concerne les pièces jointes. Ainsi, je suis sûr qu'il ya un concept de niveau supérieur que je suis absent sur. Peut-indice de quelqu'un me sur la façon dont les pièces jointes travaillent dans SMTP?

Était-ce utile?

La solution

Qu'est-ce que vous voulez vérifier est le module email. Il vous permet de construire

Autres conseils

Voici un exemple d'un message avec une pièce jointe PDF, un texte « corps » et l'envoi via Gmail.

# Import smtplib for the actual sending function
import smtplib

# For guessing MIME type
import mimetypes

# Import the email modules we'll need
import email
import email.mime.application

# Create a text/plain message
msg = email.mime.Multipart.MIMEMultipart()
msg['Subject'] = 'Greetings'
msg['From'] = 'xyz@gmail.com'
msg['To'] = 'abc@gmail.com'

# The main body is just another attachment
body = email.mime.Text.MIMEText("""Hello, how are you? I am fine.
This is a rather nice letter, don't you think?""")
msg.attach(body)

# PDF attachment
filename='simple-table.pdf'
fp=open(filename,'rb')
att = email.mime.application.MIMEApplication(fp.read(),_subtype="pdf")
fp.close()
att.add_header('Content-Disposition','attachment',filename=filename)
msg.attach(att)

# send via Gmail server
# NOTE: my ISP, Centurylink, seems to be automatically rewriting
# port 25 packets to be port 587 and it is trashing port 587 packets.
# So, I use the default port 25, but I authenticate. 
s = smtplib.SMTP('smtp.gmail.com')
s.starttls()
s.login('xyz@gmail.com','xyzpassword')
s.sendmail('xyz@gmail.com',['xyz@gmail.com'], msg.as_string())
s.quit()

Voici un exemple que je Snipped sur une demande de travail que nous avons fait. Il crée un e-mail HTML avec une pièce jointe Excel.

  import smtplib,email,email.encoders,email.mime.text,email.mime.base

  smtpserver = 'localhost'
  to = ['email@somewhere.com']
  fromAddr = 'automated@hi.com'
  subject = "my subject"

  # create html email
  html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
  html +='"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">'
  html +='<body style="font-size:12px;font-family:Verdana"><p>...</p>'
  html += "</body></html>"
  emailMsg = email.MIMEMultipart.MIMEMultipart('alternative')
  emailMsg['Subject'] = subject
  emailMsg['From'] = fromAddr
  emailMsg['To'] = ', '.join(to)
  emailMsg['Cc'] = ", ".join(cc)
  emailMsg.attach(email.mime.text.MIMEText(html,'html'))

  # now attach the file
  fileMsg = email.mime.base.MIMEBase('application','vnd.ms-excel')
  fileMsg.set_payload(file('exelFile.xls').read())
  email.encoders.encode_base64(fileMsg)
  fileMsg.add_header('Content-Disposition','attachment;filename=anExcelFile.xls')
  emailMsg.attach(fileMsg)

  # send email
  server = smtplib.SMTP(smtpserver)
  server.sendmail(fromAddr,to,emailMsg.as_string())
  server.quit()

Eh bien, les pièces jointes ne sont pas traités en aucune façon spéciale, ils sont « justes » les feuilles de l'arbre objet du message. Vous pouvez trouver les réponses à toutes les questions concernant mesasges conforme MIME dans cette section de la documentation sur le email .

D'une manière générale, tout type de fixation (lire: des données binaires brutes) peuvent être représentés à l'aide de base64 (Ou similaire) Content-Transfer-Encoding.

Voici comment envoyer des e-mails avec des pièces jointes de fichiers zip et utf-8 sujet + corps encodée.

Il n'a pas été facile à comprendre cela, en raison du manque de documentation et des échantillons pour ce cas particulier.

Les caractères non-ascii dans replyto doit être codé avec, par exemple, ISO-8859-1. Il existe probablement une fonction qui peut le faire.

Conseil:.
Envoyer un e-vous-mail, enregistrer et examiner le contenu de savoir comment faire la même chose en Python

Voici le code pour Python 3:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim:set ts=4 sw=4 et:

from os.path import basename
from smtplib import SMTP
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import parseaddr, formataddr
from base64 import encodebytes

def send_email(recipients=["somebody@somewhere.xyz"],
         subject="Test subject æøå",
         body="Test body æøå",
         zipfiles=[],
         server="smtp.somewhere.xyz",
         username="bob",
         password="password123",
         sender="Bob <bob@somewhere.xyz>",
         replyto="=?ISO-8859-1?Q?M=F8=F8=F8?= <bob@somewhere.xyz>"): #: bool
    """Sends an e-mail"""
    to = ",".join(recipients)
    charset = "utf-8"
    # Testing if body can be encoded with the charset
    try:
        body.encode(charset)
    except UnicodeEncodeError:
        print("Could not encode " + body + " as " + charset + ".")
        return False

    # Split real name (which is optional) and email address parts
    sender_name, sender_addr = parseaddr(sender)
    replyto_name, replyto_addr = parseaddr(replyto)

    sender_name = str(Header(sender_name, charset))
    replyto_name = str(Header(replyto_name, charset))

    # Create the message ('plain' stands for Content-Type: text/plain)
    try:
        msgtext = MIMEText(body.encode(charset), 'plain', charset)
    except TypeError:
        print("MIMEText fail")
        return False

    msg = MIMEMultipart()

    msg['From'] = formataddr((sender_name, sender_addr))
    msg['To'] = to #formataddr((recipient_name, recipient_addr))
    msg['Reply-to'] = formataddr((replyto_name, replyto_addr))
    msg['Subject'] = Header(subject, charset)

    msg.attach(msgtext)

    for zipfile in zipfiles:
        part = MIMEBase('application', "zip")
        b = open(zipfile, "rb").read()
        # Convert from bytes to a base64-encoded ascii string
        bs = encodebytes(b).decode()
        # Add the ascii-string to the payload
        part.set_payload(bs)
        # Tell the e-mail client that we're using base 64
        part.add_header('Content-Transfer-Encoding', 'base64')
        part.add_header('Content-Disposition', 'attachment; filename="%s"' %
                        os.path.basename(zipfile))
        msg.attach(part)

    s = SMTP()
    try:
        s.connect(server)
    except:
        print("Could not connect to smtp server: " + server)
        return False

    if username:
        s.login(username, password)
    print("Sending the e-mail")
    s.sendmail(sender, recipients, msg.as_string())
    s.quit()
    return True

def main():
    send_email()

if __name__ == "__main__":
    main()
# -*- coding: utf-8 -*-

"""
Mail sender
"""

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

import smtplib
import pystache
import codecs
import time

import sys
reload(sys)
sys.setdefaultencoding('utf-8')


HOST = 'smtp.exmail.qq.com'
PORT = 587
USER = 'your@mail.com'
PASS = 'yourpass'
FROM = 'your@mail.com'

SUBJECT = 'subject'
HTML_NAME = 'tpl.html'
CSV_NAME = 'list.txt'
FAILED_LIST = []


def send(mail_receiver, mail_to):
    # text = mail_text
    html = render(mail_receiver)

    # msg = MIMEMultipart('alternative')
    msg = MIMEMultipart('mixed')
    msg['From'] = FROM
    msg['To'] = mail_to.encode()
    msg['Subject'] = SUBJECT.encode()

    # msg.attach(MIMEText(text, 'plain', 'utf-8'))
    msg.attach(MIMEText(html, 'html', 'utf-8'))

    try:
        _sender = smtplib.SMTP(
            HOST,
            PORT
        )
        _sender.starttls()
        _sender.login(USER, PASS)
        _sender.sendmail(FROM, mail_to, msg.as_string())
        _sender.quit()
        print "Success"
    except smtplib.SMTPException, e:
        print e
        FAILED_LIST.append(mail_receiver + ',' + mail_to)


def render(name):
    _tpl = codecs.open(
        './html/' + HTML_NAME,
        'r',
        'utf-8'
    )
    _html_string = _tpl.read()
    return pystache.render(_html_string, {
        'receiver': name
    })


def main():
    ls = open('./csv/' + CSV_NAME, 'r')
    mail_list = ls.read().split('\r')

    for _receiver in mail_list:
        _tmp = _receiver.split(',')
        print 'Mail: ' + _tmp[0] + ',' + _tmp[1]
        time.sleep(20)
        send(_tmp[0], _tmp[1])

    print FAILED_LIST


main()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top