我的知识记录

Python批量删除垃圾邮件 imaplib清理收件箱

用imaplib按发件人、主题关键词筛选垃圾邮件,加\Deleted标志并expunge彻底删除,带dry-run预览防止误删,附完整可运行代码。

场景痛点

订阅的营销邮件、退信、钓鱼广告,每天收件箱攒几十封,手动删要点半天。按发件人、主题关键词把这些垃圾邮件批量清掉,再配合定期跑,收件箱只留真正要看的。但删邮件是不可逆操作,脚本必须先列出要删哪些让人确认,再真删。

用到的库

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"

# 垃圾邮件规则:发件人包含这些域名 或 主题含这些关键词
SPAM_SENDERS = ["newsletter@spam.com", "promo@marketing.cn"]
SPAM_SUBJECT_KEYWORDS = ["促销", "免费领取", "中奖", "发票异常"]

DRY_RUN = True  # True只预览不真删,确认无误后改False


def decode_str(s):
if not s:
return ""
return str(make_header(decode_header(s)))


def is_spam(msg):
sender = decode_str(msg.get("From") or "").lower()
subject = decode_str(msg.get("Subject") or "")
for s in SPAM_SENDERS:
if s.lower() in sender:
return True
for kw in SPAM_SUBJECT_KEYWORDS:
if kw in subject:
return True
return False


def clean_spam():
mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
mail.login(ACCOUNT, PASSWORD)
mail.select("INBOX")

# 先拉最近500封判断,避免扫全量历史
status, messages = mail.search(None, "ALL")
ids = messages[0].split()[-500:]

to_delete = []
for mid in ids:
_, data = mail.fetch(mid, "(BODY.PEEK[HEADER])")
msg = email.message_from_bytes(data[0][1])
if is_spam(msg):
to_delete.append((mid, decode_str(msg.get("Subject")), decode_str(msg.get("From"))))

print(f"共筛选出 {len(to_delete)} 封疑似垃圾邮件:")
for mid, subj, sender in to_delete:
print(f"  [{mid.decode()}] {subj}  <-  {sender}")

if DRY_RUN:
print("\n当前是预览模式(DRY_RUN=True),未真正删除。确认后把DRY_RUN改成False再跑。")
mail.logout()
return

# 真删:先加\Deleted标志,再expunge物理删除
for mid, _, _ in to_delete:
mail.store(mid, "+FLAGS", "\\Deleted")
mail.expunge()
print(f"\n已永久删除 {len(to_delete)} 封")
mail.logout()


if __name__ == "__main__":
clean_spam()

代码讲解

  • 删除分两步:先store(mid, "+FLAGS", "\\Deleted")给邮件打上删除标志,再expunge()把所有带这个标志的邮件从服务器物理抹掉。只store不expunge,邮件还在服务器上,只是标了个记号。
  • DRY_RUN开关:默认只打印要删的清单,不真删。这是删除类脚本必须有的安全闸,先跑一遍预览,看清单没问题再改False
  • BODY.PEEK[HEADER]:只抓邮件头来判断发件人、主题,不下载正文和附件,速度快一个数量级,也不会误标已读。
  • is_spam:自定义规则,发件人域名命中或主题命中关键词就算垃圾。规则可以按自己邮箱情况加,比如"退信""自动回复"。
  • 只扫最近500封:全量扫历史容易把正常老邮件误判,窗口小一点风险低。

运行结果

第一次跑打印所有疑似垃圾邮件的清单,不动真格。核对完把DRY_RUN改成False再跑,这些邮件从服务器上彻底删除,网页邮箱里也消失。

注意事项

  • 永久删除不可恢复,跑之前一定要先DRY_RUN预览。重要邮箱建议先在网页邮箱把重要邮件移到别的文件夹。
  • 不同邮箱删除后可能进"已删除"文件夹,expunge之后才是真没了;QQ、163一般expunge就直接清空。
  • 规则别写太宽。比如只匹配"发票"两个字,正常的"发票已开请查收"也会被删。关键词尽量长一点、特征明确一点。
  • 想更安全:不要expunge,只+FLAGS \\Deleted,让邮件进已删除文件夹,定期人工清空,给一次后悔机会。
  • 附件类垃圾邮件删之前想清楚,脚本默认不下载附件,只删邮件本身。

Python批量删除垃圾邮件 imaplib清理收件箱

标签:

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

上一篇:Python批量发送个性化邮件 模板替换姓名

下一篇:Python使用163邮箱SMTP发送邮件 完整配置