Alibaba Mail: Retrieve emails and save them as .eml files via IMAP

更新时间:
复制 MD 格式

Use Python to connect to Alibaba Mail via IMAP, retrieve emails, and save them as .eml files.

Python sample code

Scenario: Retrieve email subject and body, then save as an .eml file named email_uid_subject.eml.

Important

The following code was tested on Python 3.11.9. Test thoroughly before using in production.

# -*- coding: utf-8 -*-
import imaplib
import email
from imapclient import imap_utf7


def get_folders():
    # Get the list of mailbox folders.
    list_folder = []
    list_folder_org = conn.list()
    for i in list_folder_org[1]:
        list_folder.append(imap_utf7.decode(i).split('/" ')[1].replace('"', ''))  # Truncate the folder name.
    print(list_folder)
    return list_folder


# def get_content(msg):
#     # Decode the email body.
#     if msg.is_multipart():
#         # List
#         return get_content(msg.get_payload(0))  # Get the text from the email.
#     else:
#         # String
#         return msg.get_payload(None, decode=True)  # Get the text from the email. If True, decode base64/quoted-printable encoded content. Otherwise, do not decode.


def save_email_as_eml(msg, uid):
    # Save the email as an .eml file.
    subject = msg['Subject']
    if subject:
        try:
            # Try to decode the subject.
            decoded_subject = email.header.decode_header(subject)[0][0]
            if isinstance(decoded_subject, bytes):
                decoded_subject = decoded_subject.decode('utf-8')
            # Replace invalid characters in the filename.
            safe_subject = "".join([c if c.isalnum() or c in (' ', '.', '_') else '_' for c in decoded_subject])
            eml_filename = f"email_{uid}_{safe_subject}.eml"
        except Exception as e:
            print(f"Failed to decode subject: {e}")
            eml_filename = f"email_{uid}.eml"
    else:
        eml_filename = f"email_{uid}.eml"

    with open(eml_filename, 'w', encoding='utf-8') as f:
        f.write(msg.as_string())
    print(f"Email saved as {eml_filename}")


# Configure the IMAP server.
imap_server = 'imap.qiye.aliyun.com'  # IMAP server address
username = 'test@example.com'  # Username
password = '*********'  # Password
port = 993  # Port number

# Connect to the server and log on.
conn = imaplib.IMAP4_SSL(imap_server, port)  # SSL encrypted connection

# Authenticate and log on.
conn.login(username, password)

print('Mailbox folder list:')
get_folders()  # Get the list of mailbox folders.

folder_name = imap_utf7.encode('folder1')  # utf-7 encoding, for non-ASCII folder names.
conn.select(folder_name)  # 'draft','INBOX'   # Select a folder.
v_type, data = conn.search(None, 'UNSEEN SINCE 05-Mar-2024')  # Query for unread emails after a specific date.

email_list = data[0].split()
if len(email_list) == 0:
    print('Folder is empty. Exiting!')
    exit(1)

print('Status=', v_type, 'MSMQ ordinal number num=', data)
print('All UIDs in this folder:', conn.uid('search', None, "ALL"))
# Get the ordinal number of the last email.
item = email_list[len(email_list) - 1]
print('MSMQ ordinal number of the last email:', item)

v_status = conn.status(folder_name, '()')
v_status_1 = (v_status[1][0].decode('utf-8').replace('MESSAGES', 'Total number of emails in the mailbox:')
              .replace('RECENT', 'Number of emails flagged as RECENT in the mailbox:')
              .replace('UIDNEXT', 'Next UID that can be assigned to a new email:')
              .replace('UIDVALIDITY', 'UID validity flag of the mailbox:')
              .replace('UNSEEN', 'Unread emails:'))

print('Basic mailbox folder information:', folder_name, v_status_1)
v_count = 1
list_show_yulan = []

# Parse the email.
for num in email_list:
    v_type, data = conn.fetch(num, '(RFC822)')
    UID = conn.fetch(num, 'UID')[1]
    v_num_uid = UID[0].decode('utf-8').replace('(', '').replace(')', '').split(' ')

    print('\nParsing email ' + str(v_count) + ', num=', v_num_uid[0], ' UID=', v_num_uid[2],
          '===============================================')

    print('Server return value=', data[0])  # The returned result, including num, UID, and the original email text.
    msg = email.message_from_bytes(data[0][1])
    print('Original email text in .eml format:\n', msg)

    # Save the email as an .eml file.
    save_email_as_eml(msg, v_num_uid[2])

    v_count = v_count + 1

# conn.print_log()  # Print the IMAP log.
conn.close()

Sample output

image

image

image