이번 포스팅에서는 파이썬 내장 모듈인 SMTP를 사용하여 프로그램으로 이메일을 전송하는 실습을 진행해볼 것이다.
SMTP는 Simple Mail Transfer Protocol의 약자로, 이메일을 송/수신하는데 사용하는 TCP/IP 프로토콜이다.
쉽게 말하자면, 컴퓨터 사이에 이메일 통신을 위한 규약이라고 할 수 있다.
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
우선, SMTP를 사용하기 위해 필요한 smtplib 모듈을 import한다.
그 아래에 클래스들을 보면 MIME이라는 이름을 가지고 있는데,
MIME은 이메일과 함께 전송할 파일을 텍스트 형식으로 변환해주는 역할을 한다.
# 이메일 로그인 계정 입력
sender = str(input('이메일 : '))
password = str(input('비밀번호 : '))
# 수신자 이메일 입력
receiver = str(input('수신자 이메일 : '))
그 다음엔, 내가 사용할 메일 계정의 아이디와 패스워드를 입력받은 후에,
누구에게 메일을 전송할지까지 입력받는다.
추가적으로, SMTP를 사용하기 위해서는 SMTP 서버명 / 포트 / 계정 총 3가지의 입력값이 필요하다.
메일 제공자에 대한 SMTP 서버명과 포트는 아래 표를 통해 확인할 수 있다.
메일 Provider | SMTP 서버명 / 포트 |
Gmail | smtp.gmail.com, 587 |
Naver | smtp.naver.com, 587 |
Live | smtp.live.com, 587 |
SMTP 서버의 Encryption 방식에 따라 TLS를 사용할지, SSL을 사용할지 정해야 하는데,
TLS를 사용하는 경우 smtplib.SMTP() 클래스를 사용하고,
SSL을 사용하는 경우 smtplib.SMTP_SSL() 클래스를 사용한다고 한다.
TLS와 SSL은 네트워크 분야이기 때문에 정확히 알지는 못하지만,
'컴퓨터 네트워크에 통신 보안을 제공하기 위한 암호 규약'이라고 이해하면 쉬울 듯 하다.
위 그림처럼 Gmail의 경우 TLS용 포트가 587이라고 친절하게 설명해주고 있다.
def smtp_setting(type=None, email, password):
mail_type = None
port = 587
if type == 'naver':
mail_type = 'smtp.naver.com'
elif type == 'gmail':
mail_type = 'smtp.gmail.com'
else:
mail_type = 'smtp.gmail.com'
# SMTP 세션 생성
smtp = smtplib.SMTP(mail_type, port)
smtp.set_debuglevel(True)
# SMTP 계정 인증 설정
smtp.ehlo()
smtp.starttls() # TLS 사용시 호출
smtp.login(email, password) # 로그인
return smtp
이 함수에서는 type이라는 매개변수로 어떤 메일 Provider를 사용할지를 입력받는다.
메일 제공자에 맞춰 어떤 SMTP 서버명과 포트를 사용할지 정해야하기 때문이다.
해당 예제에서는 TLS를 사용하기 때문에 port는 587로 초기화하였고, smtplib.SMTP() 클래스를 사용하였다.
SMTP 세션을 생성하였다면, SMTP 서버에 'Hello' 라는 메세지를 보내야 하는데, 이 역할을 ehlo() 메소드가 수행해준다.
Hello 메세지 전송 후에는 starttls() 메소드를 실행하여 TLS Encryption을 시작하고,
SMTP 서버에 로그인한 smtp 객체를 반환한다.
def send_plain_mail(sender, receiver, email, password, subject, content):
try:
# SMTP 세션 생성
smtp = smtp_setting('gmail', email, password)
# 이메일 데이터 설정
msg = MIMEText(content)
msg['Subject'] = subject
msg['From'] = sender # 발신자
msg['To'] = receiver # 수신자
# 메일 전송
smtp.sendmail(sender, receiver, msg.as_string())
except Exception as e:
print('error', e)
finally:
if smtp is not None:
smtp.quit()
SMTP 초기 세팅이 끝났다면, 이제는 메일을 전송해야 할 시간이다.
메일을 전송하는 것도 그리 어렵지는 않다.
본인은 gmail을 사용하기 때문에, smtp_setting()의 매개변수 type 값으로 'gmail'을 입력하였다.
그러고 나서 MIMEText()에 전송 할 메일의 내용을 전달하여 msg 객체를 생성하고,
각각 제목(Subject), 발신자(From), 수신자(To)를 설정하여 sendmail() 메소드를 호출하면 끝이다.
send_gmail(sender, receiver, # 발신자, 수신자
sender, password, # google email, password
'안녕하세요 부나님. 프로그램 개발 의뢰 메일입니다.',# 메일 제목
'안녕하세요.\n\n프로그램 개발 의뢰드리려자 메일드렸습니다.') # 메일 내용
처음에 입력받았던 발신자와 수신자, 그리고 이메일 계정 정보와 예시를 위한 메일 제목과 내용을 입력하였다.
이제 위 코드를 실행하여 간략한 메일을 전송해보도록 하자!
코드 실행 결과, 예상했던데로 메일이 정상적으로 전송되었다.
(+ 여기서 메일이 전달되지 않고 오류가 발생하는 분들은 맨 아래에 작성한 오류 해결방법을 참고하시기 바랍니다.)
메일이 전송되었다니 너무나 기쁘지만!
메일 형식이 너무 단순하기 때문인지 별로 보기 좋아보이지는 않는다.
따라서 우리는 여기서 끝이 아니라, Multipart를 사용하여 HTML 형식의 메일을 전송해볼 것이다.
def send_multipart_mail(sender, receiver, email, password, subject, content):
try:
# SMTP 세션 생성
smtp = smtp_setting('gmail', email, password)
# 이메일 데이터 설정
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender # 송신자
msg['To'] = receiver # 수신자
# msg['To'] = ",".join(receiver) # 여러명의 수신자일 경우
# 일반 텍스트 형식의 문자열
part1 = MIMEText(content['plain'], 'plain')
# HTML 형식의 문자열
part2 = MIMEText(content['html'], 'html')
msg.attach(part1)
msg.attach(part2)
# 메일 전송
smtp.sendmail(sender, receiver, msg.as_string())
except Exception as e:
print('error', e)
finally:
if smtp is not None:
smtp.quit()
조금 달라보일 수 있지만, 전체적인 로직은 기존과 동일하다.
다만, MIMEMultipart 클래스 객체를 생성해주고, 이 객체에 attach() 메소드로 MIMEText의 객체를 덧붙여야 한다는 점이 조금 다르다.
위 예제처럼 일반 텍스트 형식의 문자열을 보내고 싶다면 MIMEText의 두번째 매개변수로 'plain'을,
HTML형식의 메일을 보내고 싶다면 'html'이라는 값을 전달해주면 된다.
아래는 메일을 전송하는 코드이다.
send_multipart_mail(sender, receiver, # 발신자, 수신자
sender, password, # google email, password
'당신을 BuNa의 ITStory 블로그로 초대합니다!', # 메일 제목
{'plain' : '당신을 BuNa의 ITStory 블로그로 초대합니다!', # 메일 내용
'html' : """
<html>
<head></head>
<body>
<h1>BuNa's ITStory</h1><br>
<p>
반갑습니다.<br>
이 사이트에 방문하시면 최고의 IT 기술을 배울 수 있습니다. <a href="https://www.itstory1592.com">ITStory</a><br>
당신이 방문하기를 원합니다!
</p><br>
<img style='width:100px height:100px;' src='https://tistory4.daumcdn.net/tistory/3146959/attach/7b3828737277425da39136f7b4bc5698'></img
</body>
</html>
"""})
매개변수 content의 값으로 딕셔너리 형태의 문자열을 전달하였다.
key값이 plain인 부분은 위에서 설명했듯이 일반 텍스트 형식의 내용이고,
html인 부분은 말 그대로 HTML 코드를 사용한 내용이다.
나는 간단한 대문 타이틀과 내용, 블로그 이미지를 덧붙여 전송해보았다.
이메일을 전송한 결과, BuNa's ITStory 라는 대문작만한 타이틀과 함께 초대 메세지와 링크, 그리고 블로그 프로필 이미지가 전송되었다.
예제에서는 간단한 HTML 코드를 사용하였지만, 어느정도 HTML/CSS가 익숙한 사람들에게는
훨씬 더 예쁘고 보기 좋은 이메일을 만들 수 있을 것이다.
오류 해결
이제 오류해결 방법에 대해 알아보도록 하자.
아마 코드를 실행시킨 대부분의 사람들이 아래와 같은 오류를 겪고 있을 것이다.
이 문장이 출력되면서 메일이 전송되지 않고 프로그램이 종료되어 버리는 문제가 발생한다.
이 오류는 메일 아래와 같은 설정을 해주면 해결된다.
- Gmail을 사용하는 경우
우선 Gmail에 로그인을 한 후 아래 링크에 접속하여 구글 계정에 대한 엑세스를 허용해준다.
https://accounts.google.com/DisplayUnlockCaptcha
링크에 접속하여 위와 같은 화면이 나타났다면 '계속' 버튼을 눌러준다.
그러면 아래와 같은 화면이 나타날 것이다.
위 화면이 정상적으로 나타났다면 다시 아래 링크에 접속한다.
https://www.google.com/settings/security/lesssecureapps
그럼 위와 같은 화면이 나타날텐데 보안 수준이 낮은 앱 허용을 '사용' 으로 바꿔주면 끝이 난다.
다시 이메일을 전송해보면 정상적으로 메일이 전송되는 것을 확인할 수 있을 것이다.
- Naver 이메일을 사용하는 경우
네이버 이메일을 사용하는 경우에는, 네이버 계정에 로그인을 한 후 네이버 메일로 접속한다.
그러면 좌측 하단에 '환경설정'이라는 텍스트 버튼이 보일 것이다.
텍스트 버튼을 눌렀으면 아래 화면이 출력될텐데,
POP3/IMAP 설정으로 들어간 후, POP3/SMTP 사용을 '사용 안 함'에서 '사용함'으로 변경해주면 된다.
그리고 확인을 눌러 변경된 정보를 저장해주고, 이메일을 전송해보면 정상적으로 과정이 이루어질 것이다.
(만약 위 과정을 모두 진행했는데도 메일이 전송되지 않으면 댓글로 해결책을 드리겠습니다.)
👍클릭으로 구독하기👍
(이해가 다소 힘들거나, 틀린 부분이 있다면 댓글 부탁드리겠습니다! 😊)
💖도움이 되셨다면 '구독'과 '공감' 부탁드립니다!💖
'Programming > 파이썬' 카테고리의 다른 글
[파이썬] 코랩에서 Python Rich 라이브러리를 사용하여 텍스트 출력을 예쁘게 꾸며보자 (16) | 2021.06.15 |
---|---|
[파이썬] Python Sqlite3 모듈을 사용하여 Database를 생성하고 데이터를 관리해보자 (10) | 2021.06.14 |
[Develop/파이썬] 셀레니움 크롤링(Crawling) - Tistory 포럼 자동 댓글 프로그램 문제점 개선하기 (45) | 2021.06.06 |
[파이썬] 코랩(CoLab)에서 구글 드라이브 파일(csv, txt ...) 가져오기 (23) | 2021.06.05 |
[Develop/파이썬] 셀레니움 크롤링(Crawling) - Tistory 포럼 자동 댓글 등록 프로그램 (37) | 2021.06.04 |