用30行Python写个属于自己的邮件监控小工具
哎呦,今天本宫来分享点真正有意思的东西——30 行 Python 代码,搞一个自己的邮件监控小工具。别慌,先把脑子里那堆“高大上”“企业级”“微服务”抛到脑后,咱们只需要几行脚本,就能让电脑帮你盯着邮箱,省得你刷抖音刷到手抽筋还在那儿等重要邮件。
先说需求,先把坑排好,省得一上来就踩。
1️⃣ 设定好邮箱的“入口钥匙”
先得搞到一个 IMAP 账号(QQ、网易、Gmail 都行),别用“登录密码”,那玩意儿在大多数平台已经不让用了。打开对应邮箱的设置 → 账户 → IMAP/SMTP,打开服务后会给你一串 授权码(也叫 App Password),这就是你脚本里要用的“钥匙”。
小提示:把授权码写成环境变量,千万别硬编码在脚本里,否则哪天你把代码丢到 GitHub 公开仓库,就等着邮箱被“友情”清空吧。本宫可不想看“救命啊,我的邮箱被黑了”的求救贴。
# Linux / macOSexport EMAIL_USER="your@email.com"export EMAIL_PASS="your_app_password"# Windows PowerShell$env:EMAIL_USER="your@email.com"$env:EMAIL_PASS="your_app_password"2️⃣ 必要的库,别装错版本
Python 自带 imaplib、email 这两个标准库,不需要再装第三方库(不需要额外 pip install)。不过,如果你想更优雅地处理 MIME,或者想用 ssl 包装加密,建议直接上 ssl.create_default_context(),省得手写 TLS。
3️⃣ 30 行代码的核心结构
下面这段代码是直接上 “最小可行版”,别急着复制粘贴,先把注释读完,了解每一步在干嘛。要不然跑起来报错,你只会说“媚娘,这脚本怎么不行”,媚娘可不背锅。
import imaplib, email, smtplib, ssl, time, osfrom email.header import decode_headerfrom email.utils import parseaddr
# 读取环境变量USER = os.getenv("EMAIL_USER")PASS = os.getenv("EMAIL_PASS")IMAP_HOST = "imap.qq.com" # 以 QQ 为例,换成你的邮箱服务器SMTP_HOST = "smtp.qq.com"SMTP_PORT = 465 # SSL 端口CHECK_INTERVAL = 60 # 每 60 秒检查一次
def decode_str(s): """解决标题乱码的恶心问题""" if not s: return "" parts = decode_header(s)[0] charset = parts[1] or "utf-8" try: return parts[0].decode(charset) except Exception: return s
def fetch_unseen(): """抓取未读邮件,返回 (发件人, 主题, 正文) 列表""" mail = imaplib.IMAP4_SSL(IMAP_HOST, 993, ssl_context=ssl.create_default_context()) mail.login(USER, PASS) mail.select("INBOX") _, data = mail.search(None, "UNSEEN") ids = data[0].split() messages = [] for uid in ids: _, raw = mail.fetch(uid, "(RFC822)") msg = email.message_from_bytes(raw[0][1]) sender = parseaddr(msg.get("From"))[1] subject = decode_str(msg.get("Subject")) body = "" if msg.is_multipart(): for part in msg.walk(): ctype = part.get_content_type() if ctype == "text/plain": body = part.get_payload(decode=True).decode(part.get_content_charset() or "utf-8") break else: body = msg.get_payload(decode=True).decode(msg.get_content_charset() or "utf-8") messages.append((sender, subject, body)) mail.logout() return messages
def send_alert(text): """收到未读邮件时给你发邮件提醒(可以是微信、短信,这里演示 SMTP)""" ctx = ssl.create_default_context() with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT, context=ctx) as server: server.login(USER, PASS) msg = f"Subject: {subject}\n\n{text}" server.sendmail(USER, USER, msg)
while True: try: unseen = fetch_unseen() if unseen: for sender, subject, body in unseen: # 这里你自定义报警逻辑,下面是发回给自己的示例 send_alert(f"发件人: {sender}\n主题: {subject}\n内容: {body[:200]}") print(f"[本宫] 发现新邮件 → {subject}") else: print("[本宫] 没有未读邮件,喝口水继续等……") except Exception as e: print(f"[本宫] 检查出错,错误信息: {e}") time.sleep(CHECK_INTERVAL)关键点解释:
imaplib.IMAP4_SSL用 SSL 加密连接,省得手写starttls。mail.search(None, "UNSEEN")只拉未读邮件,省流量。decode_str处理标题里各种乱七八糟的编码,别让它变成一堆问号。send_alert用 SMTP 把信息再发回去,你可以改成调用企业微信、钉钉或 Twilio SMS API,这里只演示最原始的方式,省得你再装一堆依赖。CHECK_INTERVAL决定监控频率,别把服务器轮询得跟 DDoS 似的,60 秒足矣。
4️⃣ 常见“坑”,媚娘帮你们排雷
- 授权码写错:很多人把授权码复制时多敲了空格或换行,导致登录失败。别笑,真的有人把 “app-password ” 当成 “app-password” 用,媚娘只能叹气。
- IMAP 端口写错:QQ 用 993,Gmail 用 993,网易用 993,163 用 993 好吧,反正大多数都是 993,除非你用的是老掉牙的 143(未加密)。写错了你会得到 “connection refused” 或者 “bad authentication”,到时候别问媚娘。
- SSL 上下文不写:
imaplib.IMAP4_SSL默认会校验证书,大多数情况下够用。但如果你在企业内网,可能因为自签名证书导致报错,这时候可以ssl._create_unverified_context()临时绕过,不过媚娘强烈建议把公司根证书加进去,别偷懒。 - 重复提醒:脚本跑起来后,你可能会收到“重复提醒”。因为每轮循环都会拉一次未读邮件,若你不把邮件标记为已读,它们永远都是未读。建议在
fetch_unseen之后mail.store(uid, "+FLAGS", "\\Seen"),媚娘这里就不演示了,留给爱折腾的你。 - 日志输出:脚本跑在后台时,print 语句会被
systemd或screen吞掉。媚娘建议改用logging模块,把日志写进文件,配合logrotate管理。
5️⃣ 进阶玩味,让媚娘再给你点甜
- 多邮箱聚合:把
fetch_unseen改成接受host, user, pass参数,写一个循环遍历多个邮箱,实现“一站式监控”。不过别一次拉太多,免得被服务器判定为异常行为,封号可不是闹着玩的。 - 关键词过滤:在
send_alert前加个if "urgent" in subject.lower():只推送紧急邮件,省得天天收到垃圾营销邮件轰炸。 - 定时报告:把每 10 条未读邮件的摘要存到
sqlite,每天定时跑一次脚本生成报表,发给你自己。这样你周末在家也能看到“有哪些工作邮件被遗漏”,媚娘可不想你因为刷抖音错失老板的紧急邮件。
6️⃣ 收尾,媚娘的最后唠叨
好啦,30 行代码已经给你扔出来了。别再把这段脚本当成玩具,跑在服务器上让它天天盯着邮箱,省得你每天还得打开网页手动刷新。
媚娘提醒一句:技术本身不怕蠢,怕的是你不肯动脑。把这套东西跑通之后,你可以把它包装成 systemd service,或者 Docker 容器,甚至用 cron 定时任务去调用——只要记得把环境变量写进 .env,别再让密码裸奔。
好了,赶紧去试试,别忘了给媚娘点个赞,顺便把代码贴到评论区让媚娘检查检查有没有写错。媚娘可是会盯着你们的哦,别想着偷懒!
……哼,等你跑通的那天,记得回来告诉媚娘:“媚娘,真香!”
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时






