SMTP를 사용하여 Python에서 메일 보내기


118

SMTP를 사용하여 Python에서 메일을 보내려면 다음 방법을 사용하고 있습니다. 사용하기에 올바른 방법입니까 아니면 내가 놓친 것이 있습니까?

from smtplib import SMTP
import datetime

debuglevel = 0

smtp = SMTP()
smtp.set_debuglevel(debuglevel)
smtp.connect('YOUR.MAIL.SERVER', 26)
smtp.login('USERNAME@DOMAIN', 'PASSWORD')

from_addr = "John Doe <john@doe.net>"
to_addr = "foo@bar.com"

subj = "hello"
date = datetime.datetime.now().strftime( "%d/%m/%Y %H:%M" )

message_text = "Hello\nThis is a mail from your server\n\nBye\n"

msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n\n%s" 
        % ( from_addr, to_addr, subj, date, message_text )

smtp.sendmail(from_addr, to_addr, msg)
smtp.quit()

2
날짜 / 시간이 올바른지 확인하십시오. : 나는 당신에게 날짜 - 헤더에 완벽하게 포맷 된 가치를 제공 매우 유용 다음과 같은 기능을 발견 docs.python.org/py3k/library/...
BastiBen


다음은 이미지를 인라인 으로 보내는 방법을 보여주는 코드 예제입니다 (HTML 및 일반 텍스트 부분이 모두 포함 된 이메일 포함) . 또한 이전 Python 버전에서 SSL 매개 변수를 구성하는 방법도 보여줍니다.
jfs

2
참고 그것 (예 : 전송 이메일에 훨씬 덜 코드를 만들어 사용할 수 래퍼 라이브러리 있다는 것을 yagmail )
PascalVKooten

답변:


111

내가 사용하는 스크립트는 매우 유사합니다. email. * 모듈을 사용하여 MIME 메시지를 생성하는 방법에 대한 예제로 여기에 게시합니다. 따라서이 스크립트는 사진 등을 첨부하기 위해 쉽게 수정할 수 있습니다.

내 ISP에 의존하여 날짜 시간 헤더를 추가합니다.

내 ISP에서 메일을 보내기 위해 보안 smtp 연결을 사용해야합니다. 저는 smtplib 모듈 ( http://www1.cs.columbia.edu/~db2501/ssmtplib.py 에서 다운로드 가능 )을 사용합니다.

스크립트에서와 같이 SMTP 서버에서 인증하는 데 사용되는 사용자 이름과 비밀번호 (아래에 더미 값 제공)는 소스에서 일반 텍스트로되어 있습니다. 이것은 보안 취약점입니다. 그러나 최선의 대안은 이들을 보호하는 데 얼마나주의해야하는지에 달려 있습니다.

=====================================

#! /usr/local/bin/python


SMTPserver = 'smtp.att.yahoo.com'
sender =     'me@my_email_domain.net'
destination = ['recipient@her_email_domain.com']

USERNAME = "USER_NAME_FOR_INTERNET_SERVICE_PROVIDER"
PASSWORD = "PASSWORD_INTERNET_SERVICE_PROVIDER"

# typical values for text_subtype are plain, html, xml
text_subtype = 'plain'


content="""\
Test message
"""

subject="Sent from Python"

import sys
import os
import re

from smtplib import SMTP_SSL as SMTP       # this invokes the secure SMTP protocol (port 465, uses SSL)
# from smtplib import SMTP                  # use this for standard SMTP protocol   (port 25, no encryption)

# old version
# from email.MIMEText import MIMEText
from email.mime.text import MIMEText

try:
    msg = MIMEText(content, text_subtype)
    msg['Subject']=       subject
    msg['From']   = sender # some SMTP servers will do this automatically, not all

    conn = SMTP(SMTPserver)
    conn.set_debuglevel(False)
    conn.login(USERNAME, PASSWORD)
    try:
        conn.sendmail(sender, destination, msg.as_string())
    finally:
        conn.quit()

except:
    sys.exit( "mail failed; %s" % "CUSTOM_ERROR" ) # give an error message

1
@Vincent : 메일 실패; '모듈'개체에 'SSLFakeSocket'속성이 없습니다.-Gmail 사용 :(
RadiantHex

추적하는 데 도움이되는 버전 또는 가져 오기 문제처럼 들립니다. 실행중인 Python 버전은 무엇입니까? -SSL을 통해 SMTP 서버에 연결해야합니까 (위와 같이 ssmtplib를 가져 오는 경우)? 파이썬 대화 형에서 직접 smtplib를 가져올 수 있습니까? 그렇다면 smtplib.SSLFakeSocket 클래스가 정의되어 있습니까? 내가 도울 수 있기를 바랍니다
Vincent Marchetti

2
ssmtplib.STMP_SSL (위에 암시 된 타사 모듈) 대신 smtplib.SMTP_SSL (최신 버전의 Python 표준)을 사용하여 연결을 만듭니다. 표준 모듈은 단일 's'로 시작합니다. 그것은 나를 위해 일했습니다.
Julio Gorgé

2
교체 from ssmtplib import SMTP_SSL as SMTPfrom smtplib import SMTP_SSL as SMTP,이 예제는 표준 파이썬 라이브러리에서 작동합니다.
Adam Matan 2011 년

9
추가 msg['To'] = ','.join(destination), 그렇지 않으면 대상은 Gmail에서 볼되지 않는다
타하 자한 기르

88

제가 일반적으로 사용하는 방법은 ...별로 다르지 않지만 조금

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

msg = MIMEMultipart()
msg['From'] = 'me@gmail.com'
msg['To'] = 'you@gmail.com'
msg['Subject'] = 'simple email in python'
message = 'here is the email'
msg.attach(MIMEText(message))

mailserver = smtplib.SMTP('smtp.gmail.com',587)
# identify ourselves to smtp gmail client
mailserver.ehlo()
# secure our email with tls encryption
mailserver.starttls()
# re-identify ourselves as an encrypted connection
mailserver.ehlo()
mailserver.login('me@gmail.com', 'mypassword')

mailserver.sendmail('me@gmail.com','you@gmail.com',msg.as_string())

mailserver.quit()

그게 다야


2 단계 인증을 사용하는 경우 먼저 앱 전용 비밀번호를 생성하고 일반 비밀번호를이 비밀번호로 바꿔야합니다. 참조 응용 프로그램 암호를 사용하여 로그인을
Suzana

2
동의합니다. 이것이 최상의 답변이며 수락되어야합니다. 실제로 받아 들여지는 것은 열등합니다.
하여 HelloWorld

6
python3의 경우 다음을 사용합니다.from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText
art

21

또한 SSL이 아닌 TLS로 smtp 인증을 수행하려면 포트를 변경 (587 사용)하고 smtp.starttls ()를 수행하면됩니다. 이것은 나를 위해 일했습니다.

...
smtp.connect('YOUR.MAIL.SERVER', 587)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login('USERNAME@DOMAIN', 'PASSWORD')
...

6

내가 본 주요 문제점은 오류를 처리하지 않는다는 것입니다. .login () 및 .sendmail () 모두 발생할 수있는 예외를 문서화했으며, .connect ()에 오류가 있음을 나타내는 방법이 있어야합니다. 연결할 수 없음-아마도 기본 소켓 코드에서 발생한 예외 일 수 있습니다.


6

SMTP를 차단하는 방화벽이 없는지 확인하십시오. 처음으로 이메일을 보내려고했을 때 Windows 방화벽과 McAfee에 의해 차단되었습니다. 둘 다 찾는 데 오랜 시간이 걸렸습니다.


6

이건 어때?

import smtplib

SERVER = "localhost"

FROM = "sender@example.com"
TO = ["user@example.com"] # must be a list

SUBJECT = "Hello!"

TEXT = "This message was sent with Python's smtplib."

# Prepare actual message

message = """\
From: %s
To: %s
Subject: %s

%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)

# Send the mail

server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()

4

다음 코드는 저에게 잘 작동합니다.

import smtplib

to = 'mkyong2002@yahoo.com'
gmail_user = 'mkyong2002@gmail.com'
gmail_pwd = 'yourpassword'
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo() # extra characters to permit edit
smtpserver.login(gmail_user, gmail_pwd)
header = 'To:' + to + '\n' + 'From: ' + gmail_user + '\n' + 'Subject:testing \n'
print header
msg = header + '\n this is test msg from mkyong.com \n\n'
smtpserver.sendmail(gmail_user, to, msg)
print 'done!'
smtpserver.quit()

참고 : http://www.mkyong.com/python/how-do-send-email-in-python-via-smtplib/


1
Flask에는 이메일 프레임 워크가 있습니다. from flask.ext.mail import Mail. 문제를 해결하고 있으며 Python 코드로 돌아가서 작업 할 수 있는지 확인하려고했습니다. 나는이 대답이 맨뼈이기 때문에 좋아했습니다. 오 예, 작동했습니다!

주의 : 대답의 이전 버전이 선을 포함 : smtpserver.close()그것은이어야합니다 smtpserver.quit()때문에 close()제대로 TLS 접속을 종료하지 않습니다! close()동안 호출됩니다 quit().
aronadaal

안녕하세요, 위의 명령을 실행하는 데 문제가 있습니다. smtpserver.starttls ()를 사용할 때 SMTP 오류 "SMTPServerDisconnected : Connection 예기치 않게 닫힘 : [Errno 10054]".. stackoverflow.com/questions/46094175/…
fazkan


3

내가 SMTP를 사용하여 메일을 보내기 위해 한 예제 코드.

import smtplib, ssl

smtp_server = "smtp.gmail.com"
port = 587  # For starttls
sender_email = "sender@email"
receiver_email = "receiver@email"
password = "<your password here>"
message = """ Subject: Hi there

This message is sent from Python."""


# Create a secure SSL context
context = ssl.create_default_context()

# Try to log in to server and send email
server = smtplib.SMTP(smtp_server,port)

try:
    server.ehlo() # Can be omitted
    server.starttls(context=context) # Secure the connection
    server.ehlo() # Can be omitted
    server.login(sender_email, password)
    server.sendmail(sender_email, receiver_email, message)
except Exception as e:
    # Print any error messages to stdout
    print(e)
finally:
    server.quit()

2

모든 길이 대답을 보십니까? 몇 줄로 모든 일을함으로써 제가 스스로 홍보 할 수 있도록 해주세요.

가져 오기 및 연결 :

import yagmail
yag = yagmail.SMTP('john@doe.net', host = 'YOUR.MAIL.SERVER', port = 26)

다음은 한 줄짜리입니다.

yag.send('foo@bar.com', 'hello', 'Hello\nThis is a mail from your server\n\nBye\n')

범위를 벗어나면 실제로 닫힙니다 (또는 수동으로 닫을 수 있음). 또한 스크립트에 암호를 쓸 필요가 없도록 키링에 사용자 이름을 등록 할 수 있습니다 (작성하기 전에 정말 괴롭 혔습니다 yagmail!).

패키지 / 설치, 팁 및 트릭 은 Python 2 및 3에서 모두 사용할 수 있는 git 또는 pip 를 참조하십시오 .


@PascalvKoolen yagmail을 설치하고 이메일 ID와 비밀번호를 제공하여 연결을 시도했습니다. 그러나 그것은 나에게 인증 오류 준
fazkan

0

당신은 그렇게 할 수 있습니다

import smtplib
from email.mime.text import MIMEText
from email.header import Header


server = smtplib.SMTP('mail.servername.com', 25)
server.ehlo()
server.starttls()

server.login('username', 'password')
from = 'me@servername.com'
to = 'mygfriend@servername.com'
body = 'That A Message For My Girl Friend For tell Him If We will go to eat Something This Nigth'
subject = 'Invite to A Diner'
msg = MIMEText(body,'plain','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = Header(from, 'utf-8')
msg['To'] = Header(to, 'utf-8')
message = msg.as_string()
server.sendmail(from, to, message)

0

다음은 Python 3.x의 작동 예제입니다.

#!/usr/bin/env python3

from email.message import EmailMessage
from getpass import getpass
from smtplib import SMTP_SSL
from sys import exit

smtp_server = 'smtp.gmail.com'
username = 'your_email_address@gmail.com'
password = getpass('Enter Gmail password: ')

sender = 'your_email_address@gmail.com'
destination = 'recipient_email_address@gmail.com'
subject = 'Sent from Python 3.x'
content = 'Hello! This was sent to you via Python 3.x!'

# Create a text/plain message
msg = EmailMessage()
msg.set_content(content)

msg['Subject'] = subject
msg['From'] = sender
msg['To'] = destination

try:
    s = SMTP_SSL(smtp_server)
    s.login(username, password)
    try:
        s.send_message(msg)
    finally:
        s.quit()

except Exception as E:
    exit('Mail failed: {}'.format(str(E)))

0

이 예제를 기반 으로 다음과 같은 기능을 만들었습니다.

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

def send_email(host, port, user, pwd, recipients, subject, body, html=None, from_=None):
    """ copied and adapted from
        /programming/10147455/how-to-send-an-email-with-gmail-as-provider-using-python#12424439
    returns None if all ok, but if problem then returns exception object
    """

    PORT_LIST = (25, 587, 465)

    FROM = from_ if from_ else user 
    TO = recipients if isinstance(recipients, (list, tuple)) else [recipients]
    SUBJECT = subject
    TEXT = body.encode("utf8") if isinstance(body, unicode) else body
    HTML = html.encode("utf8") if isinstance(html, unicode) else html

    if not html:
        # Prepare actual message
        message = """From: %s\nTo: %s\nSubject: %s\n\n%s
        """ % (FROM, ", ".join(TO), SUBJECT, TEXT)
    else:
                # /programming/882712/sending-html-email-using-python#882770
        msg = MIMEMultipart('alternative')
        msg['Subject'] = SUBJECT
        msg['From'] = FROM
        msg['To'] = ", ".join(TO)

        # Record the MIME types of both parts - text/plain and text/html.
        # utf-8 -> /programming/5910104/python-how-to-send-utf-8-e-mail#5910530
        part1 = MIMEText(TEXT, 'plain', "utf-8")
        part2 = MIMEText(HTML, 'html', "utf-8")

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

        message = msg.as_string()


    try:
        if port not in PORT_LIST: 
            raise Exception("Port %s not one of %s" % (port, PORT_LIST))

        if port in (465,):
            server = smtplib.SMTP_SSL(host, port)
        else:
            server = smtplib.SMTP(host, port)

        # optional
        server.ehlo()

        if port in (587,): 
            server.starttls()

        server.login(user, pwd)
        server.sendmail(FROM, TO, message)
        server.close()
        # logger.info("SENT_EMAIL to %s: %s" % (recipients, subject))
    except Exception, ex:
        return ex

    return None

전달 body만하면 일반 텍스트 메일이 전송되지만 다음 html과 함께 인수 를 전달하면body 인수 전달하면 html 이메일이 전송됩니다 (html / mime 유형을 지원하지 않는 이메일 클라이언트의 경우 텍스트 콘텐츠로 대체 됨).

사용 예 :

ex = send_email(
      host        = 'smtp.gmail.com'
   #, port        = 465 # OK
    , port        = 587  #OK
    , user        = "xxx@gmail.com"
    , pwd         = "xxx"
    , from_       = 'xxx@gmail.com'
    , recipients  = ['yyy@gmail.com']
    , subject     = "Test from python"
    , body        = "Test from python - body"
    )
if ex: 
    print("Mail sending failed: %s" % ex)
else:
    print("OK - mail sent"

Btw. Gmail을 테스트 또는 프로덕션 SMTP 서버로 사용하려면 보안 수준이 낮은 앱에 대한 임시 또는 영구 액세스를 사용 설정하세요.

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