Python IMAP 메일 연동

2024. 11. 8. 13:10·개발/PYTHON
728x90
반응형

파이썬 메일 연동을 알아보자

파이썬에 내장된 라이브러리 imaplib를 통해 메일서버에 접속하여 가져올 수 있다.

메일을 보내고 싶을땐 smtplib를 사용한다.

 

SMTP/IMAP 통신 절차

 

사용중인 메일의 설정을 보면 IMAP/SMTP host와 port 정보가 나오고

사용여부를 설정할 수 있다.

 

mailplug의 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
'개발/PYTHON' 카테고리의 다른 글
  • PYTHON - 재귀 함수 (피보나치, 하노이의 탑, 최소공배수 등)
  • Python 용량 변환
  • CGI, WSGI, ASGI
  • Python 3.11 소식
joolog
joolog
  • joolog
    JOO
    joolog
  • 전체
    오늘
    어제
    • 분류 전체보기 (163)
      • 개발 (81)
        • JAVA (29)
        • PYTHON (9)
        • AWS (15)
        • DOCKER (2)
        • PERCONA (2)
        • ORACLE (12)
        • MYSQL (1)
        • 알고리즘 (0)
        • 기타 (11)
      • 툴 (5)
        • MARKDOWN (1)
        • GIT (1)
        • DOCKER (1)
        • PyCharm (2)
        • IntelliJ (0)
      • 일상 (35)
        • 맛집 (6)
        • 카페 (2)
        • 요리 (4)
        • 글씨 연습 (2)
        • 그저 일상 (7)
        • 내돈 내산 (11)
        • 홍보 (1)
      • 국내 여행 (1)
      • 해외 여행 (15)
        • 체코-오스트리아 (10)
        • 일본 (5)
      • 암 일지 (26)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • 관리
    • 티스토리 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    mysql
    글씨연습
    동위원소
    저요오드식
    오블완
    자바
    재발
    오라클
    jdbc
    잘츠부르크
    히로시마
    오스트리아
    성모샘쉼터
    Oracle
    요양병원
    오닉스 리프3
    티스토리챌린지
    체코
    갑상선 암
    자바JDBC
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
joolog
Python IMAP 메일 연동
상단으로

티스토리툴바