How to Extract Data From Emails With Python

Last updated July 2026

Try it now: extract email data to Excel, CSV, or JSON

Convert your email files
No install

Connect a mailbox to pull .eml/.msg in bulk, or paste a raw email to test the converter now.

or paste an email to test
Output format
Columns to extract
Extract your own custom fields
Popular:

Create a free account to download. No credit card required.

Want the data without maintaining a script?

MailParse reads each email, pulls the fields you name into clean columns, and returns them as JSON to your app or a spreadsheet, with no imaplib code to babysit. See the email parser API, or write the Python yourself below.

Python is the fastest way to prove that email data can be pulled out programmatically. The standard library alone gets you a working script in an afternoon: imaplib connects to the mailbox, the email module parses each message into headers and body, and a few regular expressions lift the order number or invoice total out of the text. This guide shows the whole path, then explains the point where a hand-written script costs more to maintain than it saves.

Last updated July 2026.

How do I extract data from an email using Python?

To extract data from an email using Python, connect to the mailbox with imaplib, fetch each message, parse it with the email module into headers and a body, then use regular expressions or string methods to pull the fields you want. The body text carries the values, so once you have it as a string you match patterns like an order number or a dollar amount and write them to a row.

Python script to extract data from email

A minimal script has three parts: connect and search, fetch and parse, then extract. Here is the shape of it against a standard IMAP mailbox:

import imaplib, email, re
from email.header import decode_header

M = imaplib.IMAP4_SSL("imap.gmail.com")
M.login("[email protected]", "app-password")
M.select("INBOX")

# find the emails you care about
status, data = M.search(None, '(SUBJECT "Order confirmation")')
for num in data[0].split():
    status, msg_data = M.fetch(num, "(RFC822)")
    msg = email.message_from_bytes(msg_data[0][1])

    # get the plain-text body
    body = ""
    if msg.is_multipart():
        for part in msg.walk():
            if part.get_content_type() == "text/plain":
                body = part.get_payload(decode=True).decode(errors="ignore")
    else:
        body = msg.get_payload(decode=True).decode(errors="ignore")

    # pull the fields with regex
    order = re.search(r"Order #(\w+)", body)
    total = re.search(r"Total:\s*\$([\d,.]+)", body)
    print(order.group(1) if order else "", total.group(1) if total else "")

M.logout()

That prints an order number and total for every matching email. Swap the search filter and the regex patterns for your own senders and you have a working extractor. For Outlook or Microsoft 365, point IMAP4_SSL at outlook.office365.com and authenticate with OAuth or an app password.

How do I extract data from an Outlook email using Python?

To extract data from an Outlook email using Python, connect over IMAP to outlook.office365.com with imaplib, or read a saved .msg file with a library such as extract-msg. Parse the message into body text, then apply the same regex or split logic to pull the fields. The extraction step is identical to Gmail; only the connection and authentication change.

How do I extract the body text from an email in Python?

Use the email module: call email.message_from_bytes() on the raw message, check is_multipart(), and walk the parts to find the text/plain section, decoding it with get_payload(decode=True). Many emails also carry a text/html part, which you often need instead when the useful data sits in an HTML table rather than plain text.

Where a Python script stops paying off

The script above works until the emails vary. Real inboxes are messy: one supplier writes Total: $1,240.00, another writes Amount due 1240.00 USD, a third puts the figure inside an HTML table with inline styles. Each variation is a new regex, and every sender who redesigns their template silently breaks a pattern you wrote months ago. Below is the honest trade-off.

Concern Python script Hosted parser or API
SetupAn hour if you know imaplibPoint at fields, no code
Layout variationA new regex per formatHandles variation on the field
HTML tablesYou parse the DOM yourselfRows mapped to columns
MaintenanceYou own every breakMaintained for you
Best forOne or two stable sendersMany senders, changing formats

A script is the right tool when you have one or two senders whose format never changes and you enjoy owning the code. Once you are chasing a dozen templates, or the people who need the data cannot read Python, a hosted parser earns its cost by removing the maintenance. If you would rather not manage separate IMAP logins for every account, a service that lets you connect every mailbox in one place takes that piece off your plate too.

Can I get the parsed fields back as JSON?

Yes. A parser returns each email as a structured object with your named fields, which is easier to consume than raw regex output. MailParse reads the subject, body, and HTML tables, then returns one clean record per email. Developers can call the email parser API to receive that record as JSON, or export a JSON file directly.

What about attachments?

Python can list attachments through the email module, and so can a parser. The honest limit is the same in both cases: reading the contents inside a PDF or scanned attachment is a separate document-extraction job, not email parsing. MailParse records each attachment by filename, type, and size and reads the message body and HTML tables into fields; file contents are handled by a dedicated document tool. See extracting data from email attachments for where that line sits.

Should I build or buy an email parser?

Build when the job is small, stable, and yours to maintain; buy when volume, sender variety, or non-developer users make a script a liability. Many teams start with a Python proof of concept to confirm the data is extractable, then move to a parsing API once it becomes a production dependency. Read what email parsing is for the concepts behind either route.