Extract email attachments in bulk
Saving attachments one by one is the slowest part of any inbox cleanup. This is how to pull them all into a folder automatically.
What “bulk extraction” actually means
You connect to the mailbox over IMAP, walk every message, find parts that have a filename, decode the payload and write it to disk. No cloud service needed — files never leave your machine.
import imaplib, email, os, re
imap = imaplib.IMAP4_SSL("imap.example.com")
imap.login("user@example.com", "APP_PASSWORD")
imap.select("INBOX", readonly=True)
status, data = imap.search(None, 'ALL')
os.makedirs("attachments", exist_ok=True)
seen = {}
for num in data[0].split():
status, msg_data = imap.fetch(num, "(RFC822)")
msg = email.message_from_bytes(msg_data[0][1])
for part in msg.walk():
name = part.get_filename()
if not name:
continue
name = re.sub(r'[\\/:*?"<>|]', "_", name)
base, ext = os.path.splitext(name)
seen[name] = seen.get(name, 0) + 1
if seen[name] > 1:
name = f"{base}_{seen[name]}{ext}"
with open(os.path.join("attachments", name), "wb") as f:
f.write(part.get_payload(decode=True))
Four details that break naive scripts
- Duplicate names — invoices are often all called
invoice.pdf. Add a counter. - Illegal characters — filenames may contain
/,:or emoji; sanitize. - Encoded names — RFC 2047 headers need decoding, otherwise you get garbage names.
- Inline images — signature logos look like attachments; filter by
Content-Disposition: attachmentif you only want real files.
Provider limits
| Provider | Note |
|---|---|
| Gmail | Large attachments may be split; “All Mail” duplicates label copies |
| Outlook / M365 | OAuth may be required for corporate accounts |
| Yandex / Mail.ru | App password required; IMAP must be enabled in settings |
| Corporate servers | May throttle after hundreds of fetches — add a small delay |
If you need attachments plus a spreadsheet of senders and dates, one pass over the mailbox can produce both — no need to download twice.
FAQ
Can I download attachments from Gmail without a script?
Not in bulk. Gmail has no built-in “save all attachments” function; you need a client, a script or a paid tool.
Will this work with .eml files on disk?
Yes — read the file with email.message_from_bytes and iterate msg.walk() the same way.
Are attachments stored in the cloud by the script?
No. The script runs locally and writes files to a folder on your machine.
Related guides
- IMAP → ExcelThe same connection, spreadsheet output instead of files.
- Invoices from emailB2B workflow: attachments plus a payment table.