달나라 노트

Python smtplib : smtplib를 이용하여 mail 보내기 2 본문

Python/Python smtplib

Python smtplib : smtplib를 이용하여 mail 보내기 2

CosmosProject 2021. 6. 26. 04:22
728x90
반응형

 

 

 

 

 







python에서 smtplib를 이용한 mail 보내기 첫 번째 예시는 아래 링크에 있습니다.
https://cosmosproject.tistory.com/319

 

Python smtplib : smtplib를 이용하여 mail 보내기 1

Python의 smtplib를 이용하면 mail을 보낼 수 있습니다. 예시 코드는 아래와 같습니다. 먼저 gmail을 이용한 예시입니다. import smtplib from email.mime.text import MIMEText from email.mime.multipart import..

cosmosproject.tistory.com




이번엔 비슷하지만 좀 다른 형식으로 메일을 보내보겠습니다.
먼저 메일 제목, 메일 본문 등과 같이 텍스트로만 있는 메일은 아래 예시처럼 보낼 수 있습니다.

import smtplib
from email.mime.text import MIMEText


sender = 'sender@gmail.com'
recipient = 'recipient@gmail.com'
cc = 'cc@gmail.com'

title = 'Test mail'
contents = '''
This is test mail
using smtplib.
'''


msg = MIMEText(contents) # 1

msg['Subject'] = title # 2
msg['From'] = sender # 2
msg['To'] = recipient # 2
msg['Cc'] = cc # 2

smtp_server = smtplib.SMTP('host') # 3
smtp_server.sendmail(from_addr=sender, to_addrs=recipient, msg=msg.as_string()) # 4
smtp_server.quit() # 5


1. MIMEText class를 생성합니다.

2. MIMEText class에 메일 제목, 발신자, 수신자, 참조(cc) 정보를 넣어줍니다.

3. smtp server에 접근합니다.

4. mail을 보냅니다.
이 경우 예시에 명시된 parameter들을 모두 명시해줘야 합니다.

5. smtp server를 종료합니다.












저희가 메일을 보낼 때에는 문자만 보내는 것은 아닙니다.
여러 파일들을 첨부하곤하죠.

그러면 smtplib를 이용할 때 파일 첨부는 어떻게 할 수 있는지 봐봅시다.
예시는 아래와 같습니다.

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

sender = 'sender@gmail.com'
recipient = 'recipient@gmail.com'
cc = 'cc@gmail.com'

title = 'Test mail'
contents = '''
This is test mail
using smtplib.
'''

attach_file_name = 'test_excel.xlsx'

msg = MIMEMultipart() # 1
msg['From'] = sender # 1
msg['To'] = recipient # 1
msg['Subject'] = title # 1
msg['Cc'] = cc # 1

msg.attach(MIMEText(contents, 'plain')) # 2
attached_file = open(attach_file_name, 'rb').read() # 3
att = MIMEBase('application', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet') # 4
# att = MIMEBase('application', 'octet-stream') # 4-1
# att = MIMEBase('application', 'octate-stream') # 4-2

att.set_payload(attached_file) # 5
encoders.encode_base64(att) # 6
att.add_header('Content-Disposition', 'attachment', filename=attach_file_name)) # 7
# att.add_header('Content-Disposition', 'attachment; filename=\"{file_name}\"'.format(file_name=attach_file_name)) # 7-1

msg.attach(att) # 8
smtp_server = smtplib.SMTP('host') # 9
smtp_server.sendmail(from_addr=sender, to_addrs=recipient, msg=msg.as_string()) # 10
smtp_server.quit() # 11

 

1. MIMEMultipart 객체를 생성하고, 발신자/수신자/메일제목/참조 정보를 넣어줍니다.

2. 본문 내용(contents)을 MIMEText를 이용하여 msg 객체에 더해줍니다.

3. 첨부할 파일을 열고(open) 읽습니다.(read) -> 첨부파일의 내용을 attached_file 변수에 insert합니다.

(이 때 파일을 열기 위해선 open method에 첨부할 file의 경로를 명시해줘야합니다.)

(만약 python 파일과 동일한 경로에 첨부할 파일이 있다면 파일 이름만 상대경로로 명시해주면 됩니다.)

4. 파일 첨부를 위해 MIMEBase 객체를 생성합니다.
여기서 첫 번째 인자는 application이라는 텍스트를 적어주면 되지만, 두 번쨰 인자는 변할 수 있습니다.
일단 attch_file_name 변수에 첨부할 파일명이 적혀있는데, 확장자가 xlsx인 것을 보니 엑셀 파일입니다.

.xlsx 파일의 경우 MIMEBase의 두 번째 parameter는 vnd.openxmlformats-officedocument.spreadsheetml.sheet 로 적어야 합니다.
(참고로 .csv 파일의 경우도 동일한 셋팅값으로 첨부가 가능합니다.)

이에 관련되어 파일 형식 별로 어떻게 적어야하는지에 대한 내용은 아래 링크를 참조하면 됩니다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

 

Common MIME types - HTTP | MDN

Here is a list of MIME types, associated by type of documents, ordered by their common extensions.

developer.mozilla.org


이와는 별도로 만약 텍스트만 보낼거라면 4-1, 4-2처럼 셋팅해도 됩니다.


5. set_payload를 이용해서 file 내용을 첨부합니다.

6. 첨부파일을 encoding합니다.

7. 첨부파일에 header를 추가해줍니다.
만약 header 추가 작업을 거쳐주지 않으면 내가 첨부할 파일명이 보존되지 않고 AT00001.xlsx같은 형식으로 전송됩니다.
따라서 원본 파일의 이름을 보존하고싶으면 add_header를 해줘야합니다.

add_header에서 file_name=~~ 부분이 첨부된 파일의 이름이 됩니다.

add_header는 7-1과 같은 형식으로 명시해줘도 됩니다.

8. msg 객체에 첨부할 파일 내용을 attach해줍니다.

9. smtp server에 연결합니다.

10. sendmail을 이용해서 메일을 보냅니다.
이때 예시에 명시된 3개의 parameter를 반드시 명시해줘야 합니다.

11. smtp server를 종료합니다.







 

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

sender = 'sender@gmail.com'
recipient = 'recipient@gmail.com'
cc = 'cc@gmail.com'

title = 'Test mail'
contents = '''
This is test mail
using smtplib.
'''

attach_file_name_1 = 'test_excel_1.xlsx'
attach_file_name_2 = 'test_image.png'

msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = recipient
msg['Subject'] = title
msg['Cc'] = cc



##### attach file 1
msg.attach(MIMEText(contents, 'plain'))
attached_file = open(attach_file_name_1, 'rb').read()
att = MIMEBase('application', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet')

att.set_payload(attached_file)
encoders.encode_base64(att)
att.add_header('Content-Disposition', 'attachment', filename=attach_file_name))

msg.attach(att)



##### attach file 2
msg.attach(MIMEText(contents, 'plain'))
attached_file = open(attach_file_name_2, 'rb').read()
att = MIMEBase('application', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet')

att.set_payload(attached_file)
encoders.encode_base64(att)
att.add_header('Content-Disposition', 'attachment', filename=attach_file_name_2))

msg.attach(att)



smtp_server = smtplib.SMTP('host')
smtp_server.sendmail(from_addr=sender, to_addrs=recipient, msg=msg.as_string())
smtp_server.quit()

 

첨부하는 방식은 동일하지만 위 예시처럼 첨부 과정을 여러 번 반복하면

하나의 메일에 여러 개의 첨부파일을 첨부할 수 있습니다.

 

그리고 위 예시에서 attach_file_name_2 = 'test_image.png' 처럼 이미지를 첨부하는 것도 가능합니다.

 

 

 

 

 

 

이번에는 동시에 여러 사람에게 보내는 방법을 알아봅시다.

굉장히 간단합니다.

 

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

sender = 'sender@gmail.com'
recipient = ['recipient@gmail.com', 'recipient2@gmail.com']
cc = 'cc@gmail.com'

title = 'Test mail'
contents = '''
This is test mail
using smtplib.
'''

attach_file_name_1 = 'test_excel_1.xlsx'
attach_file_name_2 = 'test_image.png'

msg = MIMEMultipart()
msg['From'] = sender
msg['Subject'] = title
msg['Cc'] = cc



##### attach file 1
msg.attach(MIMEText(contents, 'plain'))
attached_file = open(attach_file_name_1, 'rb').read()
att = MIMEBase('application', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet')

att.set_payload(attached_file)
encoders.encode_base64(att)
att.add_header('Content-Disposition', 'attachment', filename=attach_file_name))

msg.attach(att)



##### attach file 2
msg.attach(MIMEText(contents, 'plain'))
attached_file = open(attach_file_name_2, 'rb').read()
att = MIMEBase('application', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet')

att.set_payload(attached_file)
encoders.encode_base64(att)
att.add_header('Content-Disposition', 'attachment', filename=attach_file_name_2))

msg.attach(att)



smtp_server = smtplib.SMTP('host')
smtp_server.sendmail(from_addr=sender, to_addrs=recipient, msg=msg.as_string())
smtp_server.quit()

바뀐건 recipient 뿐입니다.

 

변경 전 -> recipient = 'recipient@gmail.com'

변경 후 -> recipient = ['recipient@gmail.com', 'recipient2@gmail.com']

기존에는 recipient가 이메일 하나였지만 list의 형태로 메일을 받을 이메일을 모두 적어주면 됩니다.

 

 

변경 전 -> msg['To'] = recipient

변경 후 -> 삭제

또한 한 가지 주의할 점은 기존에 msg['To']에 recipient를 할당하는 위 부분이 삭제되었다는 것입니다.

그 이유는 msg['To'], msg['Cc] 등과 같이 msg의 각 key에 값을 할당해줄 때 이 key들은 단일 값을 받습니다. list 타입의 값은 받지 못하기 때문입니다.

 

그러면 msg['To']에 아무것도 지정하지 않고 보내도 되는가? 라는 의문이 들죠.

정답을 먼저 말하면 msg['To']에 아무것도 지정하지 않고 보내도 됩니다.

 

msg['To']에 recipient를 지정하면 이 값은 단순히 수신자가 받은 메일에 수신자 목록을 표시해주기 위함입니다.

따라서 msg['To']를 지정하지 않으면 단순히 수신자의 메일에 수신자 목록이 보이지 않는 것 뿐입니다.

 

 

 

 

 

 

728x90
반응형

'Python > Python smtplib' 카테고리의 다른 글

Python smtplib : smtplib를 이용하여 mail 보내기 1  (0) 2021.06.26
Comments