Basic flow
Key actions
SELECT
Selects a mailbox to be the target of the current operation.
SEARCH
Searches for emails that meet specific conditions.
FETCH
Retrieves the details of a specific email.
Important: The following code was tested in Python 3.11.9. Test the code thoroughly before you use it in a production environment.
Python code example
Scenario: Log in to a mailbox, select the inbox, search for unread emails, and retrieve the original EML content of the emails.
# -*- coding: utf-8 -*-
import imaplib
from imapclient import imap_utf7
imap_server = 'imap.qiye.aliyun.com'
username = 'test@example.com'
password = '********'
imap_port = 993
# Connect to the IMAP server
mail = imaplib.IMAP4_SSL(imap_server, imap_port)
mail.login(username, password)
# Select a mailbox (for example, "INBOX")
folder_name = imap_utf7.encode('INBOX') # UTF-7 encoding for Chinese characters
mail.select(folder_name)
# Search for unread emails
status, data = mail.search(None, 'UNSEEN')
if status == 'OK':
mail_ids = data[0].split()
for mail_id in mail_ids:
# Get the full content of the email
status, msg_data = mail.fetch(mail_id, '(RFC822)')
if status == 'OK':
print(f"Email ID: {mail_id.decode()}")
print("Email body:")
print(msg_data[0][1].decode())
# Close the connection
mail.logout()
Parameter examples
Notes for SELECT
Chinese folder names must be UTF-7 encoded.
import imaplib
from imapclient import imap_utf7
imap_server = 'imap.qiye.aliyun.com'
username = 'test@example.com'
password = '******'
port = 993
mail = imaplib.IMAP4_SSL(imap_server, port)
# Log on
mail.login(username, password)
# Select a mailbox (for example, "Inbox")
folder_name = imap_utf7.encode('Inbox') # Use UTF-7 to encode non-ASCII folder names (e.g., Chinese).
mail.select(folder_name)
print('Mailbox selected')
FAQ
If a folder encoding fault occurs, use the list command to view the folder name. For Chinese encoding, use imap_utf7.
imaplib.IMAP4.error: SELECT command error: BAD [b'invalid command or parameters']
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)Supported parameters for SEARCH
import imaplib
from imapclient import imap_utf7
imap_server = 'imap.qiye.aliyun.com'
username = 'test@example.com'
password = '******'
port = 993
mail = imaplib.IMAP4_SSL(imap_server, port)
# Log on
mail.login(username, password)
# Select a mailbox (for example, "INBOX")
folder_name = imap_utf7.encode('INBOX') # UTF-7 encoding for Chinese characters
mail.select(folder_name)
# search examples
status, data = mail.search(None, 'SEEN') # Read
# status, data = mail.search(None, 'UNSEEN') # Unread
# status, data = mail.search(None, 'ALL') # All
# status, data = mail.search(None, '(SEEN)') # Alternative syntax
# status, data = mail.search(None, '(SEEN UNSEEN)') # Supports multiple conditions
# status, data = mail.search(None, 'SEEN', ' UNSEEN') # Supports multiple conditions, separated by commas
# status, data = mail.search(None, '1') # UID
# status, data = mail.search(None, '(1 2)') # UIDs # Supports multiple UIDs
# status, data = mail.search(None, 'ON 10-Jan-2024') # Search for emails from a specific day
# status, data = mail.search(None, 'SINCE 10-Jan-2024') # Search for emails on or after a specific day
# status, data = mail.search(None, "(SINCE 05-Dec-2023 BEFORE 12-Jan-2024)") # SINCE is the start date, BEFORE is the end date
#
# status, data = mail.search(None, 'BEFORE', '12-Jan-2024', 'SEEN') # Search for emails before a specific date, excluding that date
# status, data = mail.search(None, 'BEFORE', '12-Jan-2024', 'SEEN', 'ON 05-Dec-2023') # Supports multiple conditions. ON searches for emails from a specific day
# status, data = mail.search(None, 'BEFORE 12-Jan-2024', 'SEEN', 'ON 05-Dec-2023') # Alternative syntax
# status, data = mail.search(None, 'BEFORE 12-Jan-2023 SEEN ON 05-Dec-2022')
# status, data = mail.search(None, "SENTSINCE 26-Mar-2024") # Emails sent since a specific date
print(status, data) # Returns UID information
Run result

Unsupported parameter examples for SEARCH
# mail.search(None, '(SUBJECT "Subject")')
# mail.search(None, 'SUBJECT "Test"'.encode('utf-8'))
# mail.search(None, 'OR FROM "a***@example.net"', 'SUBJECT "Test"'.encode('utf-8'))
# mail.search(None, '(FROM "Nickname")')
# mail.search(None, 'FROM', '"Nickname"')
# mail.search('GB2312', 'FROM "**example**.com"')
# mail.search(None, '(FROM "Doug" SUBJECT "Example message 2")')
# mail.search(None, "FROM", '"Nickname"')
# mail.search([u'SINCE', date(2024, 1, 20)])
Supported parameters for FETCH
import imaplib
from imapclient import imap_utf7
imap_server = 'imap.qiye.aliyun.com'
username = 'test@example.com'
password = '******'
port = 993
# Connect to the IMAP server
mail = imaplib.IMAP4_SSL(imap_server, port)
mail.login(username, password)
# Select a mailbox (for example, "INBOX")
folder_name = imap_utf7.encode('INBOX') # UTF-7 encoding for Chinese characters
mail.select(folder_name)
# Search for unread emails
status, data = mail.search(None, 'UNSEEN')
if status == 'OK':
mail_ids = data[0].split()
for mail_id in mail_ids:
# Get the full content of the email
f_status, msg_data = mail.fetch(mail_id, '(RFC822)')
# f_status, msg_data = mail.fetch(num, 'UID') # v_type1= OK data1= [b'1 (UID 12)']
# f_status, msg_data = mail.fetch(num, 'BODY[]') # Equivalent to (RFC822)
# f_status, msg_data = mail.fetch(num, '(UID BODY[HEADER])') # Returns the complete file header information.
# f_status, msg_data = mail.fetch(num, '(UID BODY[HEADER.FIELDS (Subject)])') # You can specify specific fields to return in parentheses, such as Subject.
# f_status, msg_data = mail.fetch(num, '(UID BODY[TEXT])') # Email body. The returned data is a tuple of message part data.
# f_status, msg_data = mail.fetch(num, 'FLAGS')[1] # [b'3 (UID 16 FLAGS (\\Seen))'] # To get the UID, you need to process the returned data.
if f_status == 'OK':
print(f"Email ID: {mail_id.decode()}")
print("Email body:")
print(msg_data[0][1].decode())
# Close the connection
mail.logout()
Run result

Unsupported parameters for FETCH
# status, data = mail.fetch(num, '(UID BODY[HEADER.FIELDS.NOT (Subject)])')
# status, data = mail.fetch('2:3', '(RFC822)') # Range
FAQ
The following faults indicate that the parameters for the SEARCH or FETCH action are incorrect or unsupported. Use the supported command parameters as shown in the examples.
imaplib.error: SEARCH command error: BAD [b'invalid command or parameters']
imaplib.error: FETCH command error: BAD [b'invalid command or parameters']