이메일 첨부 파일을 보내려면 어떻게합니까?


283

Python을 사용하여 첨부 파일을 전자 메일로 보내는 방법을 이해하는 데 문제가 있습니다. 간단한 메시지를 이메일로 보냈습니다 smtplib. 누군가 이메일로 첨부 파일을 보내는 방법을 설명해 주시겠습니까? 온라인에는 다른 게시물이 있지만 Python 초보자는 이해하기 어렵다는 것을 알고 있습니다.


5
다음은 여러 파일을 첨부 할 수있는 간단한 구현이며 이미지를 포함 할 경우 해당 파일을 참조 할 수도 있습니다. datamakessense.com/…
AdrianBR

이 유용한 drupal.org/project/mimemail/issues/911612 이미지 첨부 파일이 관련 유형의 하위 부분에 첨부되어야한다는 것을 알았습니다 . 루트 MIME 부분에 이미지를 첨부하면 첨부 된 항목 목록에 이미지가 표시되고 outlook365와 같은 클라이언트에서 미리 볼 수 있습니다.
Hinchy

@AdrianBR PDF 파일로 이미지가 있으면 어떻게해야합니까? PNG는 줌 할 때 픽셀 문제가 있으므로 png는 나에게 좋지 않습니다.
피노키오

답변:


416

다른 하나는 다음과 같습니다.

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

첫 번째 예제와 거의 동일하지만 더 쉽게 들어갈 수 있습니다.


7
변경 가능한 기본값에주의하십시오 : stackoverflow.com/questions/101268/hidden-features-of-python/…
Gringo Suave

11
@ user589983 다른 사용자와 마찬가지로 수정을 제안하지 않으시겠습니까? 나머지 참조를 file로 변경했습니다 f.
Oli

9
Python3 개발자를위한주의 사항 : 모듈 "email.Utils"는 "email.utils"로 이름이 바뀌 었습니다
gecco

7
python2.5 +의 경우 대신 MIMEApplication 을 사용하는 것이 더 쉽습니다 . 루프의 처음 세 줄을 다음으로 줄입니다.part = MIMEApplication(open(f, 'rb').read())
mata

5
전송 된 이메일에 제목이 표시되지 않았습니다. 행을 msg [ 'Subject'] = subject로 변경 한 후에 만 ​​작동했습니다. 파이썬 2.7을 사용합니다.
Luke

70

다음은 Oli파이썬 3 에서 수정 된 버전입니다.

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

고마워하지만 기본 사항도 있습니다. 단일 첨부 파일의 구문 (경로 사용)
JinSnow

파일을 닫지 않으면 종료시 가비지 수집되거나 닫히지 만 나쁜 습관입니다. f :를 open ()으로 사용하는 것이 올바른 방법입니다.
comte may

코드가 작동하지 않습니다. 형식 (os.path.basename (f))의 잘못된 변수 이름 f는 형식 (os.path.basename (path))이어야합니다.
Chris

1
send_to는 list [str]이어야합니다
Subin

2
나에게 가장 좋은 대답은 작은 오류가 있지만 : 교체 import pathlib와 함께from pathlib import Path
AleAve81

65

이것은 내가 사용한 코드입니다.

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

코드는 Oli의 게시물과 거의 동일합니다. 모두 감사합니다

이진 파일 전자 메일 첨부 파일 문제 게시물의 코드입니다 .


2
좋은 대답입니다. 샘플 본문을 추가하는 코드도 포함되어 있으면 좋을 것입니다.
Steven Bluen

4
전자 메일 라이브러리의 최신 릴리스에서는 모듈 가져 오기가 다릅니다. 예 :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()

여기 에서 적응했습니다 .


내가 찾고있는 것이 아닙니다. 파일이 이메일 본문으로 전송되었습니다. 6 번과 7 번 줄에도 빠진 괄호가 있습니다. 우리가 점점 가까워지고 있다고 생각합니다
Richard

2
전자 메일은 일반 텍스트이므로 smtplib지원됩니다. 첨부 파일을 보내려면 MIME 메시지로 첨부하여 일반 텍스트 전자 메일로 보내십시오. 하지만 새로운 파이썬 이메일 모듈이 있습니다 : docs.python.org/library/email.mime.html
Katriel

@katrienlalex 실제 사례는 내 이해를 돕기 위해 먼 길을 갔다
Richard

1
위의 예제가 작동하지 않습니까? 편리한 SMTP 서버는 없지만 msg.as_string()MIME 멀티 파트 이메일의 본문처럼 보입니다. Wikipedia는 MIME을 설명합니다 : 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

파이썬 3을 사용하는 다른 방법 (누군가가 검색하는 경우) :

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 계정에서“ 보안 수준이 낮은 앱 ” 을 허용하십시오


6

Python 3.6에서 작업하는 Gmail 버전 (SMTP를 통해 이메일을 보낼 수 있도록 Gmail 설정을 변경해야합니다.

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

용법:

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

다른 이메일 제공 업체와 함께 사용하려면 smtp 구성을 변경하십시오.


4

내가 얻을 수있는 가장 간단한 코드는 다음과 같습니다.

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

Django 공식 문서를 기반으로했습니다.


3
귀하의 경우에는 django를 설치하여 이메일을 보내야합니다. 질문에 제대로 응답하지 않습니다
comte

@comte 'coz python은 Django에만 사용됩니다.
Auspex

5
@Auspex 그건 내 요점이다 ;-) 설정 파일을 편집하기 위해 LibreOffice를 설치하는 것과 같습니다 ...
comte

도움이되고 유익합니다. 하나의 모듈 만 가져오고, 다른 모듈이 뛰어 넘는 MIME 후프에 비해 사용이 매우 간단하고 우아합니다. 반대로, LibreOffice는 메모장보다 사용하기가 어렵습니다.
Bjorks 최고의 팬

4

다른 답변이 훌륭하지만 누군가가 대안을 찾고있는 경우 다른 접근법을 공유하고 싶었습니다.

여기서 중요한 차이점은이 방법을 사용하면 HTML / CSS를 사용하여 메시지를 형식화 할 수 있으므로 창의성을 발휘하고 전자 메일에 스타일을 적용 할 수 있다는 것입니다. HTML을 사용하지 않아도 일반 텍스트 만 사용할 수 있습니다.

이 기능을 사용하면 여러 수신자에게 전자 메일을 보낼 수 있으며 여러 파일을 첨부 할 수도 있습니다.

나는 이것을 Python 2에서만 시도했지만 3에서도 잘 작동한다고 생각합니다.

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

이게 도움이 되길 바란다! :-)


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

설명을 위해, 당신은이 링크를 올바르게 설명 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
안녕하세요, 환영합니다. 더 나은 이해를 위해 질문에 답변 할 때 항상 답변에 대한 설명을 게시하십시오
Ali

0

아래는 SoccerPlayer의 게시물 Here 에서 찾은 내용 과 xlsx 파일을 쉽게 첨부 할 수있는 다음 링크 의 조합입니다 . 여기에서 발견

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

내 코드를 사용하면 gmail을 사용하여 이메일 첨부 파일을 보낼 수 있습니다.

" Your SMTP EMAIL HERE " 에서 Gmail 주소를 설정하십시오.

" Your SMTP PASSWORD HERE_ " 에서 Gmail 계정 비밀번호를 설정하십시오.

에서 메시지 :의 방송 서비스 ___EMAIL 부분을 당신은 대상 이메일 주소를 설정해야합니다.

알람 알림 이 주제입니다.

누군가가 방에 들어간 첨부 사진 몸이다

[ "/home/pi/webcam.jpg"] 는 이미지 첨부 파일입니다.

#!/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"] )

오랜만이에요! 코드를 올바르게 작성하고 답변에 직접 포함시키는 것이 좋습니다. 그러나 여러 질문에 동일한 답변 코드를 복사하여 붙여 넣는 것은 일반적으로 싫은 일입니다. 그들이 경우 정말 같은 방법으로 해결할 수 있습니다, 당신은해야 중복 등의 질문에 플래그를 대신합니다.
Das_Geek

0

pdf를 사용한 예와 같이 전자 메일에 첨부 파일 유형을 지정할 수도 있습니다.

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)

영감 / 신용 : http://linuxcursor.com/python-programming/06-how-to-send-pdf-ppt-attachment-with-html-body-in-python-script

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.