본 페이지에서는 파이썬으로 다음 메일을 읽는 방법에 대해서 설명드리고자 합니다. 다음 메일, 네이버 메일, 네이트 메일 등 3가지 종류의 메일 서비스로 테스트를 해보았으나, 다음 메일만 정상적으로 읽어졌습니다. 네이버 메일과 네이트 메일로 시도해본 내용도 꼼꼼하게 기록해두려고 합니다.
파이썬으로 메일을 읽으려는 이유 (자동화)
다음 메일을 읽는 방법은 여러 가지가 있습니다. 스마트폰으로도 읽을 수 있고, 웹브라우저로도 읽을 수 있으며, 아웃룩이나 썬더버드 같은 프로그램을 이용해서도 읽을 수 있습니다. 이런 방식으로 메일을 읽기 위해서는 아웃룩 프로그램을 실행시키거나, 웹브라우저에 접속해야 하는 불편함이 있습니다. 사용자의 개입 없이 메일 내용을 확인하여 자동으로 회신하거나 자동으로 포워딩을 하려면 사용자의 개입 없이 모든 것이 스크립트로 동작을 해야 합니다.
이를 위해서 파이썬으로 메일을 읽는 방법을 구글링 해보았고, 시작점으로 사용할만한 파이썬 코드를 얻었습니다. 여러 가지 에러가 발생하여 스크립트를 조금 수정하였습니다. 실제로 돌려보고 제대로 동작하는 코드를 GitHub에 업데이트해두었습니다. 코드 링크도 함께 공유드립니다.
제약사항
제가 제공해드리는 스크립트는 다음과 같은 제약사항이 있습니다. 해결하기 어려운 부분도 있고 큰 어려움 없이 개선할 수 있는 부분도 있습니다. 완벽하지는 않지만 제 스크립트를 starting point로 사용하면 충분히 수고를 덜 수 있을 것이라고 생각합니다.
- 다음 2단계 인증시에 제대로 동작하지 않음. (2단계 인증 해제 필요)
- 메일 제목과 보낸 사람의 이름이 한글로 되어 있을 경우 깨져서 표시됨.
- 마지막 메일 하나만 출력됩니다.
어디까지나 예제 코드이므로 입맛에 맞게 수정해서 사용하시면 더 좋을 것 같네요.
파이썬 스크립트
전체 스크립트 코드를 아래와 같습니다.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from email.parser import HeaderParser
import imaplib, email, re
list_response_pattern = re.compile(r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)')
def parse_list_response(line):
flags, delimiter, mailbox_name = list_response_pattern.match(line).groups()
return (flags, delimiter, mailbox_name)
# Add your data here
HOST = 'imap.daum.net'
PORT = 993
USERNAME = input("ID : ")
PASSWORD = input("PW : ")
print("Step 1. Open SSL")
server = imaplib.IMAP4_SSL(HOST, port=PORT, timeout=5) # connect
print("Step 2. Login")
server.login(USERNAME, PASSWORD) # login
print("Step 3. Select INBOX")
#server.select('INBOX',readonly=True) # select mailbox aka folder
server.select()
result, data = server.search(None, "ALL") # search emails
ids = data[0] # data is a list.
id_list = ids.split() # ids is a space separated string
latest_email_id = id_list[-1] # get the latest
result, data = server.fetch(latest_email_id, "(RFC822)") # fetch email
content = data[0][1].decode('ascii')
#print("Data :", content)
msg = email.message_from_string(content)
#print("Msg :", msg)
varSubject = msg['Subject']
print("[Subject]", varSubject)
varFrom = msg['From']
print("[From]", varFrom)
varDate = msg['Date']
print("[Date]", varDate)
server.close()
server.logout()
▶ 전체 코드 (GitHub)
전체 코드는 아래의 GitHub에 접속하시면 웹으로 살펴보실 수 있습니다.
▶ 전체 코드 (GitHub Raw)
만약 바로 다운로드 할 수 있는 Raw 파일을 원하시면 아래의 경로를 이용하시면 됩니다.
https://raw.githubusercontent.com/boyinblue/test/main/python/email_read/email_read.py
$ wget https://raw.githubusercontent.com/boyinblue/test/main/python/email_read/email_read.py
위의 URL을 사용하면, wget 명령으로 한 번에 스크립트를 다운로드하실 수 있습니다.
실행 방법
파이썬 스크립트를 아래의 명령으로 실행시킵니다.
$ ./email_read.py
혹은 아래의 명령으로도 실행시킬 수 있습니다.
$ python3 email_read.py
실행하면 ID와 PW를 물어보는데 차례대로 입력하면 됩니다.
$ ./email_read.py ID : (ID 입력) PW : (PASSWORD 입력) Step 1. Open SSL Step 2. Login Step 3. Select INBOX [Subject] =?UTF-8?B?KOq0keqzoCkg7J2Y66OM7Iuk67mELOyVlOuztO2XmCw=?= =?UTF-8?B?7LmY7JWE67O07ZeYIOymieyEnSDrs7Ttl5jro4zqs4TsgrAhIQ==?= [From] =?UTF-8?B?66mU66as7Lig7ZmU7J6sIOyYqOudvOyduCDqsIDsnoXshLzthLA=?= <send2u.email@gmail.com> [Date] Fri, 26 Aug 2022 11:30:07 +0900 (KST) |
제대로 처리되었을 경우 위와 같이 Subject, From, Date 정보가 표시됩니다.
트러블슈팅
만약 'PLAIN authentication failed. (ID), invalid login or password., fail_code(430 Two-Step Verification)'와 같은 에러가 발생한다면 2단계 인증이 활성화 되어 있을 가능성이 있습니다.
$ ./email_read.py ID : (ID 입력) PW : (PASSWORD 입력) Step 1. Open SSL Step 2. Login Traceback (most recent call last): File "/home/parksejin/project/test/python/email_read/./email_read.py", line 25, in <module> server.login(USERNAME, PASSWORD) # login File "/usr/lib/python3.10/imaplib.py", line 612, in login raise self.error(dat[-1]) imaplib.IMAP4.error: b'PLAIN authentication failed. (ID), invalid login or password., fail_code(430 Two-Step Verification)' |
이 때는 다음 계정의 2단계 인증 기능을 비활성화 시키시기 바랍니다.
네이버 메일 시도 (실패)
스크립트의 17번 라인에 있는 host를 변경해서 네이버 메일을 읽어보았습니다.
구분 | host name |
기존 | HOST = 'imap.daum.net' |
변경 | HOST = 'imap.naver.com' |
위와 같이 수정하고 실행해보면 에러가 발생합니다.
$ ./email_read.py ID : (ID) PW : (PW) Step 1. Open SSL Traceback (most recent call last): File "/home/parksejin/project/test/python/email_read/./email_read.py", line 23, in <module> server = imaplib.IMAP4_SSL(HOST, port=PORT, timeout=5) # connect File "/usr/lib/python3.10/imaplib.py", line 1323, in __init__ IMAP4.__init__(self, host, port, timeout) File "/usr/lib/python3.10/imaplib.py", line 202, in __init__ self.open(host, port, timeout) File "/usr/lib/python3.10/imaplib.py", line 1336, in open IMAP4.open(self, host, port, timeout) File "/usr/lib/python3.10/imaplib.py", line 312, in open self.sock = self._create_socket(timeout) File "/usr/lib/python3.10/imaplib.py", line 1327, in _create_socket return self.ssl_context.wrap_socket(sock, File "/usr/lib/python3.10/ssl.py", line 512, in wrap_socket return self.sslsocket_class._create( File "/usr/lib/python3.10/ssl.py", line 1070, in _create self.do_handshake() File "/usr/lib/python3.10/ssl.py", line 1341, in do_handshake self._sslobj.do_handshake() ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997) |
실행해보면 "DH_KEY_TOO_SMALL" 이라는 에러가 발생합니다. 로그인을 시도하기도 이 부분은 아직 해결하지 못했습니다.
네이트 메일 시도 (실패)
스크립트의 17번 라인에 있는 host를 변경해서 네이트 메일을 읽어보았습니다.
구분 | host name |
기존 | HOST = 'imap.daum.net' |
변경 | HOST = 'imap.nate.com' |
위와 같이 수정하고 실행해보면 에러가 발생합니다.
$ ./email_read.py ID : (ID) PW : (PW) Step 1. Open SSL Step 2. Login Step 3. Select INBOX Traceback (most recent call last): File "./email_read.py", line 40, in <module> content = data[0][1].decode('ascii') AttributeError: 'int' object has no attribute 'decode' |
네이트 메일의 경우 리턴되는 형식이 달라서 조금 다르게 처리해야 될 필요가 있어 보이네요.
참고할만한 글
우분투 리눅스에서 ssmtp를 이용해서 메일을 전송하는 방법은 아래의 글을 참고하시기 바랍니다.
이상입니다.
'SW개발 > 파이썬' 카테고리의 다른 글
ModuleNotFoundError: No module named 'gtts' 해결 방법 (0) | 2022.09.27 |
---|---|
ModuleNotFoundError: No module named 'speech_recognition' 해결 방법 (0) | 2022.09.27 |
파이썬 스크립트 자동실행 방법 (#!/usr/bin/env python3) (0) | 2022.09.27 |
[우분투][파이썬] pip3: 명령이 없습니다 조치 방법 (0) | 2022.09.27 |
AttributeError: module 'collections' has no attribute 'Iterable' (0) | 2022.05.19 |
[python] requests시에 프락시 서버 설정하는 방법 + no proxy 설정하는 방법 (0) | 2022.03.10 |