Python邮件标记已读未读 imaplib设置FLAGS教程
用imaplib的store命令给邮件加/去掉\Seen标志,实现批量标记已读、恢复未读,配合自动处理流程自动清理未读红点,附完整代码。
场景痛点
脚本自动下载附件后,网页邮箱里这些邮件还顶着未读红点,每次打开都得手动点一遍。处理完的邮件希望自动标已读,处理错了又想批量恢复成未读。用imaplib的store命令直接改邮件的\Seen标志,一行命令完成,不用登录网页邮箱。
用到的库
imaplib、email都是Python标准库,无需pip安装。
# 无需安装,Python3自带
完整代码
# -*- coding: utf-8 -*-
import imaplib
import email
from email.header import decode_header, make_header
IMAP_SERVER = "imap.qq.com"
IMAP_PORT = 993
ACCOUNT = "your_account@qq.com"
PASSWORD = "your_imap_auth_code"
def decode_str(s):
if not s:
return ""
return str(make_header(decode_header(s)))
def connect():
mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
mail.login(ACCOUNT, PASSWORD)
mail.select("INBOX")
return mail
def mark_read(subject_keyword=None, sender=None):
"""把命中条件的邮件标记为已读"""
mail = connect()
criteria = ["UNSEEN"]
if sender:
criteria += ["FROM", f'"{sender}"']
status, messages = mail.search(None, *criteria)
ids = messages[0].split() if messages[0] else []
print(f"待标记已读:{len(ids)} 封")
for mid in ids:
if subject_keyword:
# 先看主题是否含关键词,避免误标
_, data = mail.fetch(mid, "(BODY.PEEK[HEADER.FIELDS (SUBJECT)])")
subj = decode_str(email.message_from_bytes(data[0][1]).get("Subject"))
if subject_keyword not in subj:
continue
# 关键:加 \Seen 标志 = 已读
mail.store(mid, "+FLAGS", "\\Seen")
print(f" 已标记已读:{mid.decode()}")
mail.logout()
def mark_unread(last_n=10):
"""把最近N封邮件恢复成未读"""
mail = connect()
status, messages = mail.search(None, "ALL")
ids = messages[0].split()[-last_n:]
for mid in ids:
# 去掉 \Seen 标志 = 未读
mail.store(mid, "-FLAGS", "\\Seen")
print(f" 已恢复未读:{mid.decode()}")
mail.logout()
if __name__ == "__main__":
# 把来自 invoices@company.com 的未读邮件全部标记已读
mark_read(sender="invoices@company.com")
# 演示:把最近5封恢复成未读(谨慎使用)
# mark_unread(last_n=5)
代码讲解
mail.store(mid, "+FLAGS", "\\Seen"):给邮件加上\Seen系统标志,邮件立刻变成已读,网页邮箱里红点消失。mail.store(mid, "-FLAGS", "\\Seen"):去掉这个标志,邮件变回未读。这个操作在网页邮箱上一般不提供,脚本反而能干。- 其他常用标志:
\\Deleted是标记删除(下一篇删除垃圾邮件用),\\Flagged是加星标。 - 注意字符串里是双反斜杠
"\\Seen",Python里表示一个反斜杠,IMAP协议要求标志名以反斜杠开头。 BODY.PEEK[HEADER.FIELDS (SUBJECT)]:只抓主题头,不抓整封邮件,又快又不会误标已读,用来做二次过滤最合适。- 先
UNSEEN搜出来再处理,避免把已经读过的邮件重复操作。
运行结果
运行后终端打印哪些邮件被标记已读。登录网页邮箱刷新,对应的未读红点消失。mark_unread反过来把最近几封邮件恢复未读,红点重新出现。
注意事项
store改FLAGS是实时生效的,直接改服务器上的邮件状态,不是改本地副本。脚本一跑网页邮箱立刻同步变化。- 标记已读前最好先打印一下要处理的邮件列表确认无误,别一上来就把几百封未读全标了。
- 恢复未读要慎用,不小心把客户邮件都标成未读,对方看不出区别,但你的未读数会爆。
- 有些邮箱(比如Exchange)对自定义标志支持不同,但
\Seen、\Deleted是RFC标准标志,所有IMAP服务器都支持。 - 配合自动下载附件脚本:下完附件就调一次
mark_read,整个流程闭环。

更新时间:2026-09-14 21:08:14