"python code for a simple script that checks pop email and saves them all into 1 .csv file"
27.1s
Add to Favorites
Cozy Upvote
Share
Export

Use Python’s built‑in poplib and email modules to connect to a POP3 server, fetch each message, extract key headers and the plain‑text body, and write everything to a single CSV file.

Quick Facts
  • Connect with POP3_SSL (port 995) for secure access.
  • Decode subjects and bodies to handle various encodings.
  • Write rows with Id, From, To, Subject, Date, Body to one CSV.
  • Enable POP in your mailbox and consider app‑passwords for 2FA.
AI Consensus
Models Agreed
  • All models use poplib to connect to a POP server and retrieve messages.
  • Every solution extracts Subject, From, Date, and Body and writes them to a CSV file.
  • Each answer stresses the need to enable POP in the mailbox and to handle authentication securely.
Points of Debate
  • Model 1 provides a detailed helper for decoding subjects and bodies, while Model 2 uses a simpler msg.get_payload() approach that may miss multipart handling.
  • Model 3 wraps the logic in a class with extra features (timestamped filenames, limiting emails), whereas Models 1 & 2 present a flat script.

Python script: POP email → single CSV

What the script does

  1. Connects to a POP3 (optionally SSL) server.
  2. Authenticates with your username/password (or app‑password).
  3. Iterates over every message on the server.
  4. Parses each message to extract:
    • Message number (id)
    • From, To, Subject, Date
    • Plain‑text body (fallback to HTML if needed)
  5. Writes a CSV file (emails.csv by default) with one row per email.

Prerequisites

  • Python 3.6+ (standard library only).
  • POP access enabled on your mailbox (e.g., Gmail: Settings → Forwarding and POP/IMAP).
  • If you use 2‑factor authentication, generate an app‑password instead of your regular password.

Full script (ready to run)

#!/usr/bin/env python3
"""
POP Email → CSV exporter
"""

import poplib
import email
from email.header import decode_header
from email import policy
import csv
import getpass
import re
from datetime import datetime

def decode_mime_header(header):
    """Decode possibly encoded header (subject, etc.)."""
    if not header:
        return ""
    parts = decode_header(header)
    decoded = ""
    for text, charset in parts:
        if isinstance(text, bytes):
            decoded += text.decode(charset or "utf-8", errors="ignore")
        else:
            decoded += text
    return decoded.strip()

def get_plain_body(msg):
    """Return the first text/plain part, or fallback to text/html."""
    if msg.is_multipart():
        for part in msg.walk():
            ctype = part.get_content_type()
            disp = str(part.get("Content-Disposition", ""))
            if "attachment" in disp:
                continue
            if ctype == "text/plain":
                payload = part.get_payload(decode=True)
                charset = part.get_content_charset() or "utf-8"
                return payload.decode(charset, errors="ignore")
        # fallback to html if no plain part
        for part in msg.walk():
            if part.get_content_type() == "text/html":
                payload = part.get_payload(decode=True)
                charset = part.get_content_charset() or "utf-8"
                return payload.decode(charset, errors="ignore")
    else:
        payload = msg.get_payload(decode=True)
        charset = msg.get_content_charset() or "utf-8"
        return payload.decode(charset, errors="ignore")
    return ""

def fetch_and_save(server, username, password,
                   port=995, use_ssl=True,
                   csv_file="emails.csv"):
    """Connect, retrieve all messages, and write them to CSV."""
    # --- connect ---
    if use_ssl:
        pop_conn = poplib.POP3_SSL(server, port)
    else:
        pop_conn = poplib.POP3(server, port)

    pop_conn.user(username)
    pop_conn.pass_(password)

    # --- list messages ---
    msg_count = len(pop_conn.list()1)
    print(f"Found {msg_count} messages")

    # --- open CSV ---
    with open(csv_file, "w", newline="", encoding="utf-8") as f:
        fieldnames = ["id", "from", "to", "subject", "date", "body"]
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()

        # --- fetch each message ---
        for i in range(1, msg_count + 1):
            try:
                resp, lines, _ = pop_conn.retr(i)
                raw = b"\n".join(lines)
                msg = email.message_from_bytes(raw, policy=policy.default)

                row = {
                    "id": i,
                    "from": msg.get("From", ""),
                    "to": msg.get("To", ""),
                    "subject": decode_mime_header(msg.get("Subject", "")),
                    "date": msg.get("Date", ""),
                    "body": re.sub(r"\s+", " ", get_plain_body(msg).strip())[:2000],
                }
                writer.writerow(row)

                if i % 10 == 0:
                    print(f"Processed {i}/{msg_count}")
            except Exception as e:
                print(f"Error on message {i}: {e}")

    pop_conn.quit()
    print(f"All messages saved to {csv_file}")

if __name__ == "__main__":
    print("=== POP → CSV exporter ===")
    server = input("POP server (e.g., pop.gmail.com): ").strip()
    username = input("Email address: ").strip()
    password = getpass.getpass("Password (or app‑password): ")

    port_input = input("Port (default 995): ").strip()
    port = int(port_input) if port_input else 995

    ssl_input = input("Use SSL? (Y/n, default Y): ").strip().lower()
    use_ssl = False if ssl_input == "n" else True

    out_file = input("Output CSV filename (default emails.csv): ").strip() or "emails.csv"

    fetch_and_save(server, username, password, port, use_ssl, out_file)

How to run

python pop_to_csv.py

Provide the POP server, credentials, and desired output filename when prompted.

Important notes

  • Enable POP in your mailbox settings before running the script.
  • For Gmail/Outlook with 2‑FA, create an app‑specific password.
  • The script writes the body as plain text; HTML parts are ignored unless no plain text is present.
  • Large mailboxes may take minutes; you can add a max_emails limit inside fetch_and_save if needed.
  • The CSV is UTF‑8 encoded, suitable for Excel or pandas (pd.read_csv('emails.csv')).

No follow-up threads yet

Dive deeper into this topic with a follow-up.

Sign in to start a follow-up thread