E-posta ekleri nasıl gönderilir?


283

Python kullanarak bir eki e-postayla gönderme konusunda sorun yaşıyorum. İle basit mesajları başarıyla e-postayla gönderdim smtplib. Birisi e-postayla nasıl ek gönderileceğini açıklayabilir mi? Çevrimiçi başka yayınlar olduğunu biliyorum ama bir Python acemi olarak onları anlamak zor buluyorum.


5
burada birden fazla dosya ekleyebilen basit bir uygulama ve hatta gömülecek resimler için bunlara atıfta bulunabilirsiniz. datamakessense.com/…
AdrianBR

Bu yararlı buldum drupal.org/project/mimemail/issues/911612 ortaya çıkıyor görüntü ekleri ilgili tip bir alt parçaya eklenmesi gerekiyor. Görüntüyü kök MIME kısmına eklerseniz, görüntüler ekteki öğeler listesinde görünebilir ve outlook365 gibi istemcilerde önizlenebilir.
Hinchy

@AdrianBR PDF dosyası olarak bir resmim varsa ne olur. Png yakınlaştırma yaparken piksel sorunları var, bu yüzden png'ler benim için iyi değil.
Pinokyo

Yanıtlar:


416

İşte bir başkası:

import smtplib
from os.path import basename
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate


def send_mail(send_from, send_to, subject, text, files=None,
              server="127.0.0.1"):
    assert isinstance(send_to, list)

    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach(MIMEText(text))

    for f in files or []:
        with open(f, "rb") as fil:
            part = MIMEApplication(
                fil.read(),
                Name=basename(f)
            )
        # After the file is closed
        part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
        msg.attach(part)


    smtp = smtplib.SMTP(server)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.close()

İlk örnekle hemen hemen aynı ... Ama içeri girmek daha kolay olmalı.



11
@ user589983 Neden diğer kullanıcılar gibi bir düzenleme önermiyorsunuz? Ben kalan başvuru değiştirdik fileiçine f.
Oli

9
Python3 geliştiricileri için uyarı: modül "email.Utils", "email.utils" olarak yeniden adlandırıldı
gecco

7
python2.5 + için MIMEApplication kullanmak daha kolay - döngü ilk üç satırını azaltır:part = MIMEApplication(open(f, 'rb').read())
mata

5
Konu gönderilen e-postada gösterilmedi. Yalnızca satırı msg ['Subject'] = Subject olarak değiştirdikten sonra çalıştı. Python 2.7 kullanıyorum.
Luke

70

İşte Olipython 3 için değiştirilmiş sürüm

import smtplib
from pathlib import Path
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
from email import encoders


def send_mail(send_from, send_to, subject, message, files=[],
              server="localhost", port=587, username='', password='',
              use_tls=True):
    """Compose and send email with provided info and attachments.

    Args:
        send_from (str): from name
        send_to (list[str]): to name(s)
        subject (str): message title
        message (str): message body
        files (list[str]): list of file paths to be attached to email
        server (str): mail server host name
        port (int): port number
        username (str): server auth username
        password (str): server auth password
        use_tls (bool): use TLS mode
    """
    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach(MIMEText(message))

    for path in files:
        part = MIMEBase('application', "octet-stream")
        with open(path, 'rb') as file:
            part.set_payload(file.read())
        encoders.encode_base64(part)
        part.add_header('Content-Disposition',
                        'attachment; filename="{}"'.format(Path(path).name))
        msg.attach(part)

    smtp = smtplib.SMTP(server, port)
    if use_tls:
        smtp.starttls()
    smtp.login(username, password)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.quit()

teşekkürler ama temel olması da iyi olurdu: tek bir ekli dosya için sözdizimi (bu yolu kullanarak)
JinSnow

dosyalarınızı kapatmazsınız, çıkışta çöp toplanır veya kapatılır, ancak kötü bir alışkanlıktır. open: ile f: doğru olanıdır.
comte

Kod çalışmıyor. Biçimdeki yanlış değişken adı f (os.path.basename (f)) biçim olmalıdır (os.path.basename (yol))
Chris

1
send_to liste [str] olmalı
Subin

2
Benim için en iyi cevabı küçük hata var ama: değiştirmek import pathlibilefrom pathlib import Path
AleAve81

65

Bu kod kullanarak sona erdi:

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import Encoders


SUBJECT = "Email Data"

msg = MIMEMultipart()
msg['Subject'] = SUBJECT 
msg['From'] = self.EMAIL_FROM
msg['To'] = ', '.join(self.EMAIL_TO)

part = MIMEBase('application', "octet-stream")
part.set_payload(open("text.txt", "rb").read())
Encoders.encode_base64(part)

part.add_header('Content-Disposition', 'attachment; filename="text.txt"')

msg.attach(part)

server = smtplib.SMTP(self.EMAIL_SERVER)
server.sendmail(self.EMAIL_FROM, self.EMAIL_TO, msg.as_string())

Kod Oli'nin gönderisi ile hemen hemen aynı. Hepinize teşekkürler

Kod ikili dosya e-posta eki sorun sonrası dayanmaktadır .


2
İyi cevap. Ayrıca örnek bir gövde metni ekleyen kod içeriyorsa iyi olurdu.
Steven Bluen

4
E-posta kitaplığının modern sürümlerinde modül ithalatı farklıdır. örneğin:from email.mime.base import MIMEBase
Varun Balupuri

27
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
import smtplib

msg = MIMEMultipart()
msg.attach(MIMEText(file("text.txt").read()))
msg.attach(MIMEImage(file("image.png").read()))

# to send
mailer = smtplib.SMTP()
mailer.connect()
mailer.sendmail(from_, to, msg.as_string())
mailer.close()

Buradan uyarlandı .


Aradığım şey değil. Dosya bir e-postanın gövdesi olarak gönderildi. Ayrıca 6. ve 7. satırda eksik parantez var. Sanırım yaklaşıyoruz
Richard

2
E-postalar düz metindir ve bunu smtplibdestekler. Ekleri göndermek için, bunları MIME mesajı olarak kodlar ve düz metin e-posta ile gönderirsiniz. Yine de yeni bir python e-posta modülü var: docs.python.org/library/email.mime.html
Katriel

@katrienlalex çalışan bir örnek anlayışım için uzun bir yol kat eder
Richard

1
Yukarıdaki örneğin çalışmadığından emin misiniz? Kullanışlı bir SMTP sunucum yok, ama baktım msg.as_string()ve kesinlikle bir MIME çok parçalı e-postanın gövdesine benziyor. Vikipedi MIME açıklıyor: en.wikipedia.org/wiki/MIME
Katriel

1
Line 6, in <module> msg.attach(MIMEText(file("text.txt").read())) NameError: name 'file' is not defined
Benjamin2002

7

Python 3 ile başka bir yol (Birisi arıyorsa):

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

fromaddr = "sender mail address"
toaddr = "receiver mail address"

msg = MIMEMultipart()

msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "SUBJECT OF THE EMAIL"

body = "TEXT YOU WANT TO SEND"

msg.attach(MIMEText(body, 'plain'))

filename = "fileName"
attachment = open("path of file", "rb")

part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)

msg.attach(part)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "sender mail password")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()

Gmail hesabınızda " daha az güvenli uygulamalara " izin verdiğinizden emin olun


6

Gmail sürümü, Python 3.6 ile çalışıyor (smtp üzerinden e-posta gönderebilmek için Gmail ayarlarınızı değiştirmeniz gerekeceğini unutmayın:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from os.path import basename


def send_mail(send_from: str, subject: str, text: str, 
send_to: list, files= None):

    send_to= default_address if not send_to else send_to

    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = ', '.join(send_to)  
    msg['Subject'] = subject

    msg.attach(MIMEText(text))

    for f in files or []:
        with open(f, "rb") as fil: 
            ext = f.split('.')[-1:]
            attachedfile = MIMEApplication(fil.read(), _subtype = ext)
            attachedfile.add_header(
                'content-disposition', 'attachment', filename=basename(f) )
        msg.attach(attachedfile)


    smtp = smtplib.SMTP(host="smtp.gmail.com", port= 587) 
    smtp.starttls()
    smtp.login(username,password)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.close()

Kullanımı:

username = 'my-address@gmail.com'
password = 'top-secret'
default_address = ['my-address2@gmail.com'] 

send_mail(send_from= username,
subject="test",
text="text",
send_to= None,
files= # pass a list with the full filepaths here...
)

Başka bir e-posta sağlayıcısıyla kullanmak için smtp yapılandırmalarını değiştirmeniz yeterlidir.


4

Alabileceğim en basit kod:

#for attachment email
from django.core.mail import EmailMessage

    def attachment_email(request):
            email = EmailMessage(
            'Hello', #subject
            'Body goes here', #body
            'MyEmail@MyEmail.com', #from
            ['SendTo@SendTo.com'], #to
            ['bcc@example.com'], #bcc
            reply_to=['other@example.com'],
            headers={'Message-ID': 'foo'},
            )

            email.attach_file('/my/path/file')
            email.send()

Resmi Django belgelerine dayanıyordu


3
senin durumda düzgün soru cevap vermemesi ... bir e-posta göndermek için django yüklemek zorunda
Kont

@comte 'coz python hiç Django için kullanılıyor, değil mi?
Auspex

5
@Auspex bu benim açımdan ;-) Bir yapılandırma dosyasını düzenlemek için LibreOffice'i yüklemek gibi ...
comte

Bunu yararlı ve bilgilendirici buluyorum. sadece bir modül içe aktarılır ve kullanımı, diğerlerinin atladığı MIME çemberlerine kıyasla oldukça basit ve zariftir. Örneğinizin aksine, LibreOffice'i kullanmak not defteri kullanmaktan daha zordur.
Bjorks bir numaralı fan

4

Diğer cevaplar mükemmel, ancak birileri alternatif arıyorsa hala farklı bir yaklaşım paylaşmak istedim.

Buradaki temel fark, bu yaklaşımı kullanarak mesajınızı biçimlendirmek için HTML / CSS kullanabilmenizdir, böylece yaratıcı olabilir ve e-postanıza biraz stil verebilirsiniz. HTML kullanmaya zorlanmasanız da, yine de yalnızca düz metin kullanabilirsiniz.

Bu işlevin, e-postayı birden çok alıcıya göndermeyi kabul ettiğine ve ayrıca birden fazla dosya eklemeye izin verdiğine dikkat edin.

Ben sadece Python 2 üzerinde denedim, ama 3 de iyi çalışması gerektiğini düşünüyorum:

import os.path
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

def send_email(subject, message, from_email, to_email=[], attachment=[]):
    """
    :param subject: email subject
    :param message: Body content of the email (string), can be HTML/CSS or plain text
    :param from_email: Email address from where the email is sent
    :param to_email: List of email recipients, example: ["a@a.com", "b@b.com"]
    :param attachment: List of attachments, exmaple: ["file1.txt", "file2.txt"]
    """
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = from_email
    msg['To'] = ", ".join(to_email)
    msg.attach(MIMEText(message, 'html'))

    for f in attachment:
        with open(f, 'rb') as a_file:
            basename = os.path.basename(f)
            part = MIMEApplication(a_file.read(), Name=basename)

        part['Content-Disposition'] = 'attachment; filename="%s"' % basename
        msg.attach(part)

    email = smtplib.SMTP('your-smtp-host-name.com')
    email.sendmail(from_email, to_email, msg.as_string())

Umarım bu yardımcı olur! :-)


2
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
import mimetypes
import email.mime.application

smtp_ssl_host = 'smtp.gmail.com'  # smtp.mail.yahoo.com
smtp_ssl_port = 465
s = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
s.login(email_user, email_pass)


msg = MIMEMultipart()
msg['Subject'] = 'I have a picture'
msg['From'] = email_user
msg['To'] = email_user

txt = MIMEText('I just bought a new camera.')
msg.attach(txt)

filename = 'introduction-to-algorithms-3rd-edition-sep-2010.pdf' #path to file
fo=open(filename,'rb')
attach = email.mime.application.MIMEApplication(fo.read(),_subtype="pdf")
fo.close()
attach.add_header('Content-Disposition','attachment',filename=filename)
msg.attach(attach)
s.send_message(msg)
s.quit()

Açıklama için, doğru bir şekilde açıkladığı bu bağlantıyı kullanabilirsiniz https://medium.com/@sdoshi579/to-send-an-email-along-with-attachment-using-smtp-7852e77623


2
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
import smtplib

msg = MIMEMultipart()

password = "password"
msg['From'] = "from_address"
msg['To'] = "to_address"
msg['Subject'] = "Attached Photo"
msg.attach(MIMEImage(file("abc.jpg").read()))
file = "file path"
fp = open(file, 'rb')
img = MIMEImage(fp.read())
fp.close()
msg.attach(img)
server = smtplib.SMTP('smtp.gmail.com: 587')
server.starttls()
server.login(msg['From'], password)
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()

2
merhaba, Hoş Geldiniz, Daha iyi anlamak için bir soruya cevap verirken lütfen her zaman cevabınızın açıklamasını gönderin
Ali

0

Aşağıda ben SoccerPlayer en görevinden buldum şeyin birleşimidir Burada ve bana bir xlsx dosyası eklemek kolaylaştırdı aşağıdaki bağlantıyı. Burada Bulundu

file = 'File.xlsx'
username=''
password=''
send_from = ''
send_to = 'recipient1 , recipient2'
Cc = 'recipient'
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = send_to
msg['Cc'] = Cc
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = ''
server = smtplib.SMTP('smtp.gmail.com')
port = '587'
fp = open(file, 'rb')
part = MIMEBase('application','vnd.ms-excel')
part.set_payload(fp.read())
fp.close()
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment', filename='Name File Here')
msg.attach(part)
smtp = smtplib.SMTP('smtp.gmail.com')
smtp.ehlo()
smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to.split(',') + msg['Cc'].split(','), msg.as_string())
smtp.quit()

0

Kodumla gmail kullanarak e-posta ekleri gönderebilirsiniz:

Gmail adresinizi " BURADA SMTP E-POSTANIZ " olarak ayarlayın

Gmail hesabı şifrenizi " SMTP ŞİFRENİZ BURADA_ " olarak ayarlayın

Gelen mesajı_ ALMAYA ___EMAIL kısmını hedef e-posta adresini ayarlamanız gerekir.

Alarm bildirimi konudur,

Birisi odaya girdi, ekli resim vücut

["/home/pi/webcam.jpg"] bir resim ekidir .

#!/usr/bin/env python
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import os

USERNAME = "___YOUR SMTP EMAIL HERE___"
PASSWORD = "__YOUR SMTP PASSWORD HERE___"

def sendMail(to, subject, text, files=[]):
    assert type(to)==list
    assert type(files)==list

    msg = MIMEMultipart()
    msg['From'] = USERNAME
    msg['To'] = COMMASPACE.join(to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text) )

    for file in files:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( open(file,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"'
                       % os.path.basename(file))
        msg.attach(part)

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo_or_helo_if_needed()
    server.starttls()
    server.ehlo_or_helo_if_needed()
    server.login(USERNAME,PASSWORD)
    server.sendmail(USERNAME, to, msg.as_string())
    server.quit()

sendMail( ["___EMAIL TO RECEIVE THE MESSAGE__"],
        "Alarm notification",
        "Someone has entered the room, picture attached",
        ["/home/pi/webcam.jpg"] )

Uzun zamandır görüşemedik! Kodunuzu doğru bir şekilde ilişkilendirdiğinizi ve doğrudan cevaba eklediğinizi görmek güzel. Ancak, genellikle aynı cevap kodunu birden fazla soruya kopyalayıp yapıştırmak hoşunuza gitmez. Onlar ise gerçekten aynı çözelti ile çözülebilir, sen gerektiğini birbirinin aynısı gibi soruları bayrak yerine.
Das_Geek

0

Ayrıca, pdf kullandığım bir örnek olarak, e-postanızda istediğiniz ek türünü de belirtebilirsiniz:

def send_email_pdf_figs(path_to_pdf, subject, message, destination, password_path=None):
    ## credits: http://linuxcursor.com/python-programming/06-how-to-send-pdf-ppt-attachment-with-html-body-in-python-script
    from socket import gethostname
    #import email
    from email.mime.application import MIMEApplication
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    import smtplib
    import json

    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    with open(password_path) as f:
        config = json.load(f)
        server.login('me@gmail.com', config['password'])
        # Craft message (obj)
        msg = MIMEMultipart()

        message = f'{message}\nSend from Hostname: {gethostname()}'
        msg['Subject'] = subject
        msg['From'] = 'me@gmail.com'
        msg['To'] = destination
        # Insert the text to the msg going by e-mail
        msg.attach(MIMEText(message, "plain"))
        # Attach the pdf to the msg going by e-mail
        with open(path_to_pdf, "rb") as f:
            #attach = email.mime.application.MIMEApplication(f.read(),_subtype="pdf")
            attach = MIMEApplication(f.read(),_subtype="pdf")
        attach.add_header('Content-Disposition','attachment',filename=str(path_to_pdf))
        msg.attach(attach)
        # send msg
        server.send_message(msg)

ilham kaynağı / kredi: http://linuxcursor.com/python-programming/06-how-to-send-pdf-ppt-attachment-with-html-body-in-python-script

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.