728x90
반응형
파이썬 메일 연동을 알아보자
파이썬에 내장된 라이브러리 imaplib를 통해 메일서버에 접속하여 가져올 수 있다.
메일을 보내고 싶을땐 smtplib를 사용한다.
사용중인 메일의 설정을 보면 IMAP/SMTP host와 port 정보가 나오고
사용여부를 설정할 수 있다.
IMAP server
import imaplib
imap = imaplib.IMAP4_SSL(host=host, port=port)
imap.login(user=email_id, password=email_pwd)
IMAP 메일함 선택
imap.select("iNBOX")
IMAP 메일 필터링
# imap.search(charset, criterion[, ...])
# UNSEEN = 읽지 않은 메일
# SINCE {DATE} = 특정 날짜 이후에 도착한 메시지
_, uid = imap.search(None, f'(UNSEEN SINCE "{yesterday}")') # 어제 이후 도착한 메일
필터링 종류
조건 | 설명 | 예시 |
ALL | 모든 메시지를 검색합니다. | imap.search(None, 'ALL') |
ANSWERED | 회신된 메시지만 검색합니다. | imap.search(None, 'ANSWERED') |
BCC | BCC 필드에 특정 이메일이 포함된 메시지를 검색합니다. | imap.search(None, 'BCC "someone@example.com"') |
BEFORE | 특정 날짜 이전에 도착한 메시지를 검색합니다. | imap.search(None, 'BEFORE "01-Jan-2024"') |
BODY | 메시지 본문에 특정 텍스트가 포함된 메시지를 검색합니다. | imap.search(None, 'BODY "important"') |
CC | CC 필드에 특정 이메일이 포함된 메시지를 검색합니다. | imap.search(None, 'CC "someone@example.com"') |
DELETED | 삭제된 메시지를 검색합니다. | imap.search(None, 'DELETED') |
FLAGGED | 플래그가 설정된 메시지를 검색합니다. | imap.search(None, 'FLAGGED') |
FROM | 발신자가 특정 이메일인 메시지를 검색합니다. | imap.search(None, 'FROM "someone@example.com"') |
HEADER | 특정 헤더 필드에서 주어진 값을 포함하는 메시지를 검색합니다. | imap.search(None, 'HEADER "Subject" "Invoice"') |
KEYWORD | 특정 키워드를 포함하는 메시지를 검색합니다. | imap.search(None, 'KEYWORD "important"') |
LABEL | 특정 라벨이 있는 메시지를 검색합니다. | imap.search(None, 'LABEL "Work"') |
NEW | 새로 도착한 메시지를 검색합니다. | imap.search(None, 'NEW') |
OLD | 오래된 메시지를 검색합니다. | imap.search(None, 'OLD') |
ON | 특정 날짜에 도착한 메시지를 검색합니다. | imap.search(None, 'ON "01-Jan-2024"') |
SINCE | 특정 날짜 이후에 도착한 메시지를 검색합니다. | imap.search(None, 'SINCE "01-Jan-2024"') |
SMALLER | 특정 크기 이하의 메시지를 검색합니다. 크기는 바이트 단위입니다. | imap.search(None, 'SMALLER 1024') |
SUBJECT | 제목에 특정 텍스트가 포함된 메시지를 검색합니다. | imap.search(None, 'SUBJECT "Meeting"') |
TEXT | 메시지 본문에 특정 텍스트가 포함된 메시지를 검색합니다. | imap.search(None, 'TEXT "urgent"') |
TO | 수신자가 특정 이메일인 메시지를 검색합니다. | imap.search(None, 'TO "someone@example.com"') |
UNANSWERED | 회신되지 않은 메시지를 검색합니다. | imap.search(None, 'UNANSWERED') |
UNDELETED | 삭제되지 않은 메시지를 검색합니다. | imap.search(None, 'UNDELETED') |
UNSEEN | 읽지 않은 메시지를 검색합니다. | imap.search(None, 'UNSEEN') |
UNFLAGGED | 플래그가 설정되지 않은 메시지를 검색합니다. | imap.search(None, 'UNFLAGGED') |
RECENT | 최근에 도착한 메시지를 검색합니다. | imap.search(None, 'RECENT') |
SEEN | 이미 읽은 메시지를 검색합니다. | imap.search(None, 'SEEN') |
SINCE AND BEFORE | 특정 날짜 사이에 도착한 메시지를 검색합니다. | imap.search(None, 'SINCE "01-Jan-2024" BEFORE "15-Jan-2024"') |
ALL AND SEEN | 모든 메시지 중에서 읽은 메시지를 검색합니다. | imap.search(None, 'ALL SEEN') |
MAIL uid 정렬
# _ = "OK"
# uid = [b'1, 2, 3, 4 ...']
# 순서 뒤집어서 최근 5개만 가져오겠다.
uids = uid[0].split()[::-1][:5]
# uids = [b'358', b'357', b'356', b'355', b'354']
Mail msg decode
# uids = [b'358', b'357', b'356', b'355', b'354']
for uid in uids:
# 메시지 가져오기
_, msg = self.imap.fetch(uid, "(RFC822)")
for response_part in msg:
if isinstance(response_part, tuple):
# 이메일을 파싱
parse_msg = email.message_from_bytes(response_part[1])
# 이메일이 여러 부분으로 나뉜 경우 처리
if parse_msg.is_multipart():
for part in parse_msg.walk():
# 'text/plain' 또는 'text/html'인 부분을 추출
if part.get_content_type() == "text/plain":
decode_msg = part.get_payload(decode=True).decode()
elif part.get_content_type() == "text/html":
decode_msg = part.get_payload(decode=True).decode()
else:
decode_msg = msg.get_payload(decode=True).decode()
Mail Header
from email.header import decode_header
from email.utils import parsedate_to_datetime
# uids = [b'358', b'357', b'356', b'355', b'354']
for uid in uids:
# 메시지 가져오기
_, msg = self.imap.fetch(uid, "(RFC822)")
byte_msg = email.message_from_bytes(msg[0][1])
# From, To, Date, Subject
subject, encoding = decode_header(byte_msg["Subject"])[0]
if type(subject) is not str:
subject = subject.decode(encoding if encoding else "utf-8")
# 날짜 형식의 헤더
mail_received_date = parsedate_to_datetime(byte_msg["Date"])
...
Mail 읽음 처리
imap.store(uid, "+FLAGS", "\\Seen")
전체 코드
더보기
import imaplib
import email
from email.header import decode_header
from email.utils import parsedate_to_datetime
imap = imaplib.IMAP4_SSL(host=host, port=port)
imap.login(user=email_id, password=email_pwd)
imap.select("iNBOX")
# imap.search(charset, criterion[, ...])
# UNSEEN = 읽지 않은 메일
# SINCE {DATE} = 특정 날짜 이후에 도착한 메시지
_, uid = imap.search(None, f'(UNSEEN SINCE "{yesterday}")') # 어제 이후 도착한 메일
# _ = "OK"
# uid = [b'1, 2, 3, 4 ...']
# 순서 뒤집어서 최근 5개만 가져오겠다.
uids = uid[0].split()[::-1][:5]
# uids = [b'358', b'357', b'356', b'355', b'354']
for uid in uids:
# 메시지 가져오기
_, msg = self.imap.fetch(uid, "(RFC822)")
for response_part in msg:
if isinstance(response_part, tuple):
# 이메일을 파싱
parse_msg = email.message_from_bytes(response_part[1])
# 이메일이 여러 부분으로 나뉜 경우 처리
if parse_msg.is_multipart():
for part in parse_msg.walk():
# 'text/plain' 또는 'text/html'인 부분을 추출
if part.get_content_type() == "text/plain":
decode_msg = part.get_payload(decode=True).decode()
elif part.get_content_type() == "text/html":
decode_msg = part.get_payload(decode=True).decode()
else:
decode_msg = msg.get_payload(decode=True).decode()
imap.store(uid, "+FLAGS", "\\Seen")
IMAPLIB DOCUMENT
https://docs.python.org/ko/3/library/imaplib.html#
imaplib — IMAP4 protocol client
Source code: Lib/imaplib.py This module defines three classes, IMAP4, IMAP4_SSL and IMAP4_stream, which encapsulate a connection to an IMAP4 server and implement a large subset of the IMAP4rev1 cli...
docs.python.org
728x90
반응형
'개발 > PYTHON' 카테고리의 다른 글
PYTHON - 재귀 함수 (피보나치, 하노이의 탑, 최소공배수 등) (0) | 2024.11.21 |
---|---|
Python 용량 변환 (0) | 2024.11.11 |
CGI, WSGI, ASGI (4) | 2024.09.12 |
Python 3.11 소식 (0) | 2022.05.23 |
PyCharm ssh sftp 연결하기 (0) | 2022.05.13 |