๐ฅ Reading Emails with Python (imaplib
)
Imagine automatically pulling reports from your inbox, monitoring for alerts, or organizing messages into folders — all with Python.
With imaplib
, Python can log into your email, search, and read messages programmatically. Let's dive into how it works.
๐ง What is imaplib
?
imaplib
is a built-in Python module that connects to email servers using the IMAP protocol (Internet Message Access Protocol).
You can use it to:
-
Log into your email
-
Search for specific messages
-
Read subject lines, bodies, and attachments
-
Automate email-based workflows
๐งฐ Requirements
-
A Gmail or IMAP-enabled email account
-
Python 3.x
-
IMAP access turned on in your email settings
-
Use of an App Password (for Gmail with 2FA)
๐ Step 1: Connect to Email Server
import imaplib
EMAIL = "youremail@gmail.com"
PASSWORD = "your_app_password"
mail = imaplib.IMAP4_SSL("imap.gmail.com")
mail.login(EMAIL, PASSWORD)
mail.select("inbox")
⚠️ Gmail requires an App Password, which you can generate here:
https://myaccount.google.com/apppasswords
๐ Step 2: Search Your Inbox
You can search using filters like FROM
, SUBJECT
, SINCE
, or UNSEEN
.
status, messages = mail.search(None, 'UNSEEN') # unread emails
email_ids = messages[0].split()
print(f"Found {len(email_ids)} new messages.")
๐จ Step 3: Fetch and Read Emails
import email
from email.header import decode_header
for num in email_ids:
status, data = mail.fetch(num, "(RFC822)")
msg = email.message_from_bytes(data[0][1])
# Decode subject
subject, encoding = decode_header(msg["Subject"])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding or "utf-8")
# From field
from_ = msg.get("From")
print(f"From: {from_}")
print(f"Subject: {subject}")
# Body
if msg.is_multipart():
for part in msg.walk():
content_type = part.get_content_type()
if content_type == "text/plain":
body = part.get_payload(decode=True).decode()
print(f"Body:\n{body}")
break
else:
body = msg.get_payload(decode=True).decode()
print(f"Body:\n{body}")
๐ Step 4: Download Attachments
import os
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
if filename:
filepath = os.path.join("downloads", filename)
with open(filepath, "wb") as f:
f.write(part.get_payload(decode=True))
print(f"Attachment saved: {filename}")
๐งน Optional: Mark Emails as Read
mail.store(num, '+FLAGS', '\\Seen')
✅ Summary
Task | Code |
---|---|
Connect | imaplib.IMAP4_SSL(...) |
Login | .login(email, password) |
Select folder | .select("inbox") |
Search | .search(None, "UNSEEN") |
Fetch | .fetch(num, "(RFC822)") |
Parse | email.message_from_bytes(...) |
⚠️ Tips & Troubleshooting
-
Use App Passwords for secure login (especially on Gmail).
-
Always handle encoding for subject lines and body text.
-
Use
try-except
blocks around network calls to avoid crashes.
๐ง Real-World Use Cases
-
๐ฉ Auto-download reports from a specific sender
-
๐ Scan inbox for OTPs or confirmation codes
-
๐งพ Build a receipt tracker from email invoices
-
๐ Trigger scripts when certain emails arrive