我的知识记录

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,整个流程闭环。

Python邮件标记已读未读 imaplib设置FLAGS教程

标签:

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

上一篇:Python把收到的Excel附件自动合并汇总

下一篇:Python接收邮件 imaplib读取邮箱完整教程