Python의 SMTP를 이용하여 E-mail 발송하기
7 minute read
실습 코드는 https://github.com/KimDoKy/WebScrapingWithPython/tree/master/chap5 에서 원본을 볼 수 있습니다.
python으로 smtp를 이용하여 email 보내기
우선 이메일 내용을 작성한 파일을 준비합니다.
../textFile.txt
다음 코드를 작성합니다.
# 이메일을 발송하기 위해서 smtplib, email 모듈을 import 합니다.
# MIME(Multipurpose Internet Mail Extensions)는 email을 위한 인터넷 표준입니다.
>>> import smtplib
>>> from email.mime.text import MIMEText
>>> email_text = open('./textFile.txt' , 'rb')
>>> msg = MIMEText(email_text.read())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/email/mime/text.py", line 34, in __init__
_text.encode('us-ascii')
AttributeError: 'bytes' object has no attribute 'encode'
# textFile.txt 안에 한글이 들어 있기 때문에 utf-8 으로 인코딩하여 열어주어야 합니다.
>>> import codecs
>>> email_text = codecs.open('./textFile.txt' , 'rb', 'utf-8')
# 읽어들인 파일의 텍스트를 MIME 객체화 한다.
>>> msg = MIMEText(email_text.read())
>>> email_text.close()
# msg 는 무엇이 들어있는 확인해보았습니다. 헤더의 내용과 email_text에서 불러온 본문이 들어있습니다.
>>> print(msg)
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
cHl0aG9u7JeQ7IScIHNtdHDrpbwg7J207Jqp7ZWcIGVtYWlsIOuwnOyGoSDsmIjsoJwg7YWN7Iqk
7Yq4IO2MjOydvOyeheuLiOuLpC4KUklQIGNoZXN0ZXIuLi4K
# 제목을 추가하였습니다.
>>> msg['Subject'] = 'Email example content %s' % email_text
# MIMEText는 처음 다루어보기 때문에, 안에 어떤 구조인지, 어떤 정보가 들어가는지 확인해봤습니다.
>>> msg
<email.mime.text.MIMEText object at 0x10db2b160>
>>> len(msg)
4
>>> for i in msg:
... print(i)
...
Content-Type
MIME-Version
Content-Transfer-Encoding
# 좀전에 위에서 추가한 제목이 추가되었습니다.
Subject
# msg안에 추가시킨 Subject만 불러와봤습니다.
>>> msg['Subject']
'Email example content <codecs.StreamReaderWriter object at 0x10db2b198>'
# 보내는 사람을 추가합니다.
>>> msg['From'] = 'makingfunk@naver.com'
# 처음이니까 MIMEText 객체의 변화를 모니터링 했습니다.
>>> len(msg)
5
>>> for i in msg:
... print(i)
...
Content-Type
MIME-Version
Content-Transfer-Encoding
Subject
From
# 바로 위에서 작성한 From이 추가 되었습니다.
# 받는 이를 추가합니다.
>>> msg['To'] = 'abmu333@hanmail.net'
# 로컬 SMTP 서버를 이용하여 email을 보냅니다.
>>> s = smtplib.SMTP('localhost')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/smtplib.py", line 251, in __init__
(code, msg) = self.connect(host, port)
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/smtplib.py", line 335, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/smtplib.py", line 306, in _get_socket
self.source_address)
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/socket.py", line 711, in create_connection
raise err
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/socket.py", line 702, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 61] Connection refused
# 로컬 SMTP 서버가 없어서 에러가 일어났습니다. 없는 경우 다른 서버를 이용하면 됩니다.
# 여기서는 gmail 서버를 사용하였습니다.
>>> smtp_gmail = smtplib.SMTP_SSL('smtp.gmail.com', 465)
>>> smtp_gmail
<smtplib.SMTP_SSL object at 0x10e00ba90>
# gmail의 비밀번호를 잃어 버려서 에러가 났습니다. 실습하기 전에 꼭 계정 정보를 확인해두세요.
>>> smtp_gmail.login(id, passwd)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/smtplib.py", line 729, in login
raise last_exception
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/smtplib.py", line 720, in login
initial_response_ok=initial_response_ok)
File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/smtplib.py", line 641, in auth
raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials 73sm9027497pemail_text.103 - gsmtp')
# login이 성공했다는 메시지가 출력됩니다.
>>> smtp_gmail.login(id, passwd)
(235, b'2.7.0 Accepted')
# 처음이니까 일일이 다 확인해봅니다.
>>> smtp_gmail
<smtplib.SMTP_SSL object at 0x10e024780>
# 메일을 발송합니다.
# SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]) // from_addr은 필수요소이지만 빈칸으로 넣어도 정상작동합니다.
>>> smtp_gmail.sendmail('makingfunk0@gmail.com','abmu333@hanmail.net', msg.as_string())
{}
>>> smtp_gmail.quit()
(221, b'2.0.0 closing connection c76sm8724276pfj.91 - gsmtp')
>>>
이메일이 정상적으로 발송되었음을 확인 할 수 있습니다.
자세한 내용은 문서를 참조하세요.
이미지 파일을 이메일에 첨부하는 예제입니다.
# 이메일을 보내기 위해 smtplib를 import합니다.
import smtplib
# 이메일에 이미지를 첨부하기 위한 모듈들도 import 합니다.
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
COMMASPACE = ', '
family = 'abmu333@hanmail.net','makingfunk0@gmail.com'
# 이메일 메세지 컨테이너를 만듭니다.
msg = MIMEMultipart()
msg['Subject'] = 'image send mail test 2'
msg['From'] = 'makingfunk0@gmail.com'
msg['To'] = COMMASPACE.join(family)
# preamble 이 어떤 역할을 하는 속성인는 모르겠습니다.
msg.preamble = 'what the..'
pngfiles = ['./img/example.png', './img/example2.png']
for file in pngfiles:
fp = open(file, 'rb')
img = MIMEImage(fp.read())
fp.close()
# 첨부한 파일의 파일이름을 입력합니다. (이 구문이 없으면 noname으로 발송됩니다.)
img.add_header('Content-Disposition', 'attachment', filename=file)
msg.attach(img)
# 로컬 서버를 통해 메일을 보낼 때
s = smtplib.SMTP('localhost')
s.sendmail(me, family, msg.as_string())
s.quit()
# 외부 SMTP 서버를 이용할 때
s = smtplib.SMTP_SSL('smtp.gmail.com', 465)
s.login(id, passwd)
s.sendmail("","",msg.as_string())
s.quit()
파일이름 지정 구문이 없다면 naname으로 가지만, naver의 메일으로 발송하면 attach(0).txt 으로 파일이 보내집니다. 즉, 메일을 받는 사람 입장에서는 이미지를 보려면 확장자를 하나하나 변경해서 봐야 합니다.
I feedback.
Let me know what you think of this article in the comment section below!
Let me know what you think of this article in the comment section below!
comments powered by Disqus