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.

Medium Python 3.9+ Aug 9, 2026 Automation & scripting 13 views 0 copies

Python code

44 lines
Python 3.9+
import 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

stdout
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

  1. Use `email.parser.BytesParser` to parse raw bytes instead of loading the entire mailbox.
  2. 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

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Automation & scripting

Related tutorials and quizzes for this topic.