Extract Attachments from mbox Mailbox Files in Python
Extract file attachments from an mbox mailbox format using Python's standard library email and mailbox modules.
Python code
44 linesimport email
import mailbox
from email.policy import default
from pathlib import Path
def extract_attachments(mbox_path, output_dir):
output_dir = Path(output_dir)
output_dir.mkdir(exist_ok=True)
mbox = mailbox.mbox(mbox_path)
for msg in mbox:
if msg.is_multipart():
for part in msg.walk():
content_disposition = part.get("Content-Disposition", "")
if "attachment" in content_disposition:
filename = part.get_filename()
if filename:
content = part.get_payload(decode=True)
file_path = output_dir / filename
file_path.write_bytes(content)
print(f"Extracted: {filename}")
if __name__ == "__main__":
mbox_data = """From: sender@example.com
To: receiver@example.com
Subject: Test email with attachment
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="boundary123"
--boundary123
Content-Type: text/plain
Hello, please find the attachment below.
--boundary123
Content-Type: text/plain; name="notes.txt"
Content-Disposition: attachment; filename="notes.txt"
These are the attachment contents.
--boundary123--
"""
mbox_path = "demo.mbox"
Path(mbox_path).write_text(mbox_data)
extract_attachments(mbox_path, "extracted_attachments")
Output
Extracted: notes.txt
How it works
This script opens an mbox file with the mailbox module and iterates over each email message. For multipart messages, walk() recursively visits every part. We check the Content-Disposition header for "attachment" and use get_filename() to retrieve the original file name. The payload is decoded with get_payload(decode=True) and written directly to the output directory.
Common mistakes
- Not checking if the message is multipart before calling walk() — single-part messages may not have attachments.
- Using `msg.get_payload()` without `decode=True` — this returns a string instead of bytes, causing errors when writing binary files.
- Not creating the output directory — use `mkdir(exist_ok=True)` to avoid FileNotFoundError.
- Assuming every attachment has a filename — always check `get_filename()` for None.
Variations
- Use `email.parser.BytesParser` to parse raw bytes instead of loading the entire mailbox.
- Filter attachments by extension or content type with `part.get_content_type()`.
Real-world use cases
- Automating inbox cleanup by extracting PDFs or invoices from exported email archives.
- Migrating attachments from an old email system into a cloud storage bucket.
- Processing email-based file delivery systems where users send data as attachments.
Sponsored
More from Automation & scripting
- Aggregate Log Errors Count by Hour in Python easy
- Automate Tweeting New Blog Posts in Python easy
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
Keep learning
Related tutorials and quizzes for this topic.