티스토리 뷰

Python

Python, 이메일보내기

hwangyoungjae 2016. 5. 24. 14:35
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

Python3.2.2사용

 

이메일을 이해하려면 우선 MIME부터 살펴볼 필요가 있다.

MIME(Multipurpose Internet Mail Extensions)는 전자우편을 위한 인터넷표준 포맷이다이메일 전송 프로토콜인 SMTP는 개발될 당시 단지 7비트 아스키문자만을 보낼수 있게 설계되었다즉 영어 이외의 언어는 전자우편을 제대로 보내고 받을수 없었다.

인터넷이 발전하면서 다양한 요구가 늘어났다비영어권 언어도 전자메일을 사용할수 있고파일을 첨부할수 있어야 했다. MIME는 아스키가 아닌 문자 인코딩을 이용해 영어가 아닌 다른 언어로 된 전자우편을 보낼수 있는 방식이다.

또한 그림음악영화과 같은 바이너리파일을 이메일로 보낼수 있다.

이메일을 작성할때 몇줄 되지 않는 글과 작은 이미지 파일을 첨부했을때이메일의 크기가 훨씬 커진 경험이 있다그 이유는 이메일 문서를 MIME로 변경하면서 크기가 커졌기 때문이다.

 

ex) sendEmail.py : 간단한 메일을 생성후 SMTP를 이용해서 메일 발송하기

# -*- coding : cp949 -*-

import smtplib #메일을 보내기 위한 SMTP관련 모듈

from email.mime.text import MIMEText

smtpHost="smtp.test.com" #smtp 서버주소

text="hello world"

msg=MIMEText(text) #텍스트가 기본인 메일을 하나 생성,텍스트는 반드시 아스키코드여야만 함

senderAddr="test@send.com" #보내는사람 주소

recipientAddr="test@rec.com" #받는사람 주소

msg['Subject']="test email"

msg['From']=senderAddr

msg['To']=recipientAddr

#SMTP서버를 이용해 메일 보내기

s=smtplib.SMTP(smtpHost)

s.connect()

s.sendmail(senderAddr,[recipientAddr],msg.as_string())

s.close()

우선 smtplib모듈을 임포트했다이는 인터넷의 SMTP ESMTP의 서버를 통해서 메일을 보낼수 있는 SMTP클라이언트 객체가 구현되어 있다쉽게 말해 SMTP를 사용해 메일을 보내고 싶을때 사용하는 모듈이다.

 

일단 간단한 메일을 하나 생성한다이때 사용하는 클래스는 MIMEText클래스로 입력받은 text값을 MIME타입 객체로 생성한다.

class email.mime.text.MIMEText(_text[, _subtype[, _charset]])

이후 생성된 MIMEText에 보내는 사람의 주소받는 사람의 주소제목을 추가한다.

위 내용은 MIME의 헤더에 저장되고 본문(contents)은 본문(Body)부분에 저장된다.

msg.as_string()를 실행하면 헤더와 본문의 상태를 볼수 있다.

 

※ MIMEText에서 한글사용하기

위의 MIMEText클래스를 생성할 때 변환하려는 데이터는 아스키코드를 사용해야 한다왜냐하면 MIMEText 클래스에서 텍스트에 대한 기본적인 처리가 아스키이기 때문이다.

만약 한글로 처리하기 위해서 Unicode, UTF-8같은 문자열코드를 사용하려면 원하는 Character Set으로 변환해주고 MIMEText클래스에서 Character Set을 지정해야 한다위의 클래스 생성자를 보면 _charset을 이용해서 Character Set을 지정할수 있다.

아래 예제를 보자

>>> from email.mime.text import MIMEText

>>> a=MIMEText('파이썬') #기본 Character Set에 한글을 사용한 경우

>>> a.as_string()

'Content-Type: text/plain; charset="us-ascii"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 8bit\n\n파이썬'

>>> u=MIMEText('파이썬'.encode('utf-8'),_charset='UTF-8') #유니코드로 변환하고 UTF-8 을 명시

>>> u.as_string()

'MIME-Version: 1.0\nContent-Type: text/plain; charset="utf-8"\nContent-Transfer-Encoding: base64\n\n7YyM7J207I2s\n'

똑같은 파이썬이라는 텍스트를 변경하는데 아래에서는 유니코드로 변환하고 Character Set을 지정했다.

겉으로 보기엔 같아보이지만 MIME타입으로 변환된 것을 보면 차이가 많다.

첫번째 예제는 '파이썬'이라는 글자가 그대로 적혀있고, Transfer-Encoding 8bit로 되어있다이렇게 되면 받는 쪽에선 '파이썬'이라는 글자를 아스키로 해석하려고 할것이다.

두번째 예제는 파이썬이 'utf-8'로 적혀 있다받는 쪽에서도 base64로 인코딩되어 있다는걸 알수 있으니 뒤에 나오는 데이터를 유니코드 문자열로 처리할수 있다.

 

>> html과 첨부파일이 있는 메일 생성하기 <<

요즘은 메일을 보낼때 텍스트만 보내는 것이 아니라 HTML문서로 보낼수도 있고 첨부파일까지 포함할수 있다.

Python에서는 아래와 같이 처리할수 있다.

 

ex) MixedType.py : 메일에 html과 이미지 파일을 첨부해서 보내기

# -*- coding : cp949 -*-

import smtplib

import mimetypes

 

from email.mime.base import MIMEBase

from email.mime.text import MIMEText

from email.mime.image import MIMEImage

 

# global value

host='smtp.test.com'

htmlFileName='logo.html'

imageFileName='logo.gif'

 

senderAddr='test@send.com' #보내는사람 주소

recipientAddr='test@rec.com' #받는사람 주소

 

# create MIMEBase

msg=MIMEBase("multipart","mixed")

 

msg['Subject']="Test email in Python 3.0"

msg['From']=senderAddr

msg['To']=recipientAddr

 

# Make MIMEType

htmlFD=open(htmlFileName,'rb')

HtmlPart=MIMEText(htmlFD.read(),_charset='UTF-8')

htmlFD.close()

 

imageFD=open(imageFileName,'rb')

ImagePart=MIMEImage(imageFD.read())

imageFD.close()

 

만들었던 mime MIMEBase에 첨부

msg.attach(ImagePart)

msg.attach(HtmlPart)

 

헤더에 첨부 파일에 대한 정보 추가

msg.add_header('Content-Disposition', 'attachment', filename=imageFileName)

 

메일발송

s=smtplib.SMTP(host)

s.connect()

s.sendmail(senderAddr,[recipientAddr],msg.as_string())

s.close()

우선 image MIME html MIME를 포함할수 있는 컨테이너 생성을 위해서 MIMEBase를 임포트한다. MIMEBase는 모든 MIME객체들의(예를 들면 MIMEText, MIMEImage, MIMEMultiPart)부모 클래스이다.

class email.mime.base.MIMEBase(_maintype, _subtype, **_params)

_maintype Contents_Type의 메이저타입, _subtype은 마이너 타입을 말한다.

Content-Type image/gif라고 하면 메이저타입은 image이고마이너타입은 gif이다.

모든 메일의 헤더를 보면 Content-Type이 있다아무 메일을 열어서 원본보기나헤더내용을 보면 Contents-Type=multipart/alternative와 같은 부분이 있을것이다. '/'을 기준으로 앞을 _maintpye, 뒤를 subtype이라고 부른다.

 

MIME-Version: 1.0

Content-Type: multipart/mixed;

             boundary="----=_Part_338621_13687458.1360821668458"

SENDID: 4201302140003250423

#네이버메일의 원문보기 기능을 이용해서 MIME문서의 원문을 볼수 있다.

 

※ MIMEType

MIMEType클래스의 기본 Content-type text/plain이다.

메일에 html, image등 여러 종류의 파일들을 포함시키려면 MIMEBase maintype이 multipart여야 하는데,

그 이유는 단일구조로 MIME컨테이너를 만들면 하나의 MIME객체만이 들어가기 때문이다.

multipart로 생성하면 내부적으로 트리구조를 만들고 MIME객체를 관리하기 때문에 MIME컨테이너에 여러개의 MIME객체를 넣을수가 있는것이다.

 

첨부파일을 추가했으면 헤더에 첨부파일에 대한 정보를 넣어줘야 한다.

그래야 메일클라이언트에서 첨부파일이 있는 메일인지 알수가 있다.

add_header()메서드를 이용하여 헤더정보를 설정할수 있다.

host SMTP서버 주소이다만약 인증이 필요하지 않은 SMTP서버를 알고 있다면 위의 예제는 잘 동작할것이다.

하지만 대부분의 SMTP서버는 아이디와 패스워드, SSL을 통한 인증을 요구하고 있기 때문에 위의 방법으론

메일을 보내기 힘들것이다.

 

>> Gmail로 메일보내기 <<

Gmail을 통해서 메일을 보내거나 받아오기 위한 정보는 아래와 같다.

받는 메일 서버(POP3)

SSL 필요

주소 : pop.gmail.com

SSL사용 : YES

포트 : 995

보내는 메일 서버(SMTP)

TLS 필요

주소 : smtp.gmail.com

인증사용 : YES

STARTTLS사용 : YES

포트 : 465 or 587

이메일주소

계정@gmail.com

password

Gmail계정 Password

그 중 SMTP에 관련된 내용을 보면서버주소는 smtp.gmail.com이고 포트번호는 587혹은 465번을 써야 하고,

STARTTLS를 써야 한다고 명시되어 있는데, TLS(Transport Layer Security) TCP/IP와 같은 통신에서 사용하는 암호규약이다.

STARTTLS는 텍스트에 대한 암호화를 업그레이드하고 확장한 버전이다. Python은 STARTLS를 위해 smltplib모듈의 starttls()메서드를 지원한다.

>>> import smtplib

>>> s=smtplib.SMTP('smtp.gmail.com',587)

>>> s.ehlo()

(250, b'mx.google.com at your service, [114.111.62.248]\nSIZE 35882577\n8BITMIME\nSTARTTLS\nENHANCEDSTATUSCODES')

>>> s.starttls()

(220, b'2.0.0 Ready to start TLS')

>>> s.ehlo()

(250, b'mx.google.com at your service, [114.111.62.248]\nSIZE 35882577\n8BITMIME\nAUTH LOGIN PLAIN XOAUTH XOAUTH2\nENHANCEDSTATUSCODES')

>>> s.login('dud****@gmail.com','****')

(235, b'2.7.0 Accepted')

smtp.gmail.com의 인증에 성공하였다.

 

아래는 로컬의 logo.html파일을 읽어서 메일의 내용을 생성하고, logo.png파일을 첨부파일로 하여

Gmail smtp에서 Naver메일로 메일을 발송하는 예제이다.

# -*- coding : cp949 -*-

import smtplib

from email.mime.base import MIMEBase

from email.mime.text import MIMEText

from email.mime.image import MIMEImage

 

host='smtp.gmail.com' #Gmail smtp server address

port='587' #smtp port

htmlfile='logo.html'

imagefile='logo.png'

 

sender='dud****@gmail.com' #sender email address

recipient='dud****@naver.com' #recipient email address

 

# Create MIMEBase

msg=MIMEBase('multipart','mixed')

msg['Subject']='Test Email in html.logo'

msg['From']=sender

msg['To']=recipient

 

# Create MIMEHtml

htmlF=open(htmlfile,'rb')

htmlPart=MIMEText(htmlF.read(),'html',_charset='utf-8')

htmlF.close()

 

# Create MIMEImage

imageF=open(imagefile,'rb')

imagePart=MIMEImage(imageF.read())

imageF.close()

 

# attach html,image

msg.attach(imagePart)

msg.attach(htmlPart)

 

# mail send

s=smtplib.SMTP(host,port)

s.set_debuglevel(1) #debuging

s.ehlo()

s.starttls()

s.ehlo()

s.login(sender,'****')

s.sendmail(sender,[recipient],msg.as_string())

s.close()

위를 실행하면 Gmail에서 보낸메일을 naver메일로 확인할수 있다.

 

※ Python3 이전 버젼의 MIME

이메일관련 모듈이름 상당수가 python3에서 이름이 변경되었다

예를 들면 email.mime.text.MIMEText python3이전 버전에서는

email.MIMEText.MIMEText이다.

Python3에서 기존 코드를 참고하여 프로그램을 작성하는 경우,

모듈의 이름이 변경된 경우를 반드시 확인하여야 한다.

 

참조 : 빠르게 활용하는 파이썬프로그래밍

'Python' 카테고리의 다른 글

Python, 네이버검색 OpenAPI이용하기  (0) 2016.05.24
Python,module socket [소켓통신]  (0) 2016.05.24
Python, bytes를 문자열로 변환하기  (0) 2016.05.24
Python, str(), repr(), ascii(),eval()  (0) 2016.05.24
Python, XML사용하기  (0) 2016.05.20
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함