资源荟 | 收集邮箱内容并输出为word格式
写在最前
亲爱的你:
为了不必要的争端,特此说明:
1.文章提及内容所涉及的安全性请自主评估,造成的不良后果责任自负。
2.本文仅作经验/学术分享,不作外售,任何个人/团体不得未经原信息分享者/本人允许,私自售卖相关信息。
3.若本文引用的内容侵犯到您的知识产权,麻烦您联系我,我会及时删除相关文章。
4.本文仅作分享,在某些条件下可能与具体实际操作存在误差,请以实际情况为准;
5.虽然本文已有指出资源来路,但还是请您关注原作者。
6.本合集不插广。
这和任何考试无关,仅仅是一次测试。
一切的开始是本人在负责某栏目期间,经常需要收集QQ邮箱中的诸多投稿,将其整理并反馈上级处理。时间久了,问题也就出现了:有时候来稿邮件很多,一篇一篇复制粘贴又很慢。如何简化工作便成为了首要事项。
得益于强大的AI工具,做了收集邮箱内容并输出为word格式的这串代码
使用方法如下
1.准备QQ邮箱授权码
登录网页版QQ邮箱,进入“设置”→“账户”。找到“POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务”,开启“IMAP/SMTP服务”。根据提示生成授权码(一串字母数字)。保存好,此授权码将作为密码用于脚本登录。
2.下载Python,保证正常运行
一定要勾选最下面的 “Add Python to PATH”
若直接安装:
先找到 python.exe 的位置,复制地址。
在电脑左下角的搜索框里输入“环境变量”,点击“编辑系统环境变量”。在打开的窗口里,点击右下角的“环境变量”按钮。在“系统变量”这一栏里,找到“Path”,选中它,然后点击“编辑”。
点击“新建”,然后把您刚才复制的Python文件夹地址粘贴进去,点“确定”。再点击“新建”,粘贴另一个地址:把刚才的地址后面加上 \Scripts,比如 C:\Users\您的名字\AppData\Local\Programs\Python\Python312\Scripts,也加进去。
一路点“确定”关闭所有窗口。
3.新建文本文档,将其尾缀改为“.py”
4.用“记事本”打开该文本文档,将以下内容全部复制并粘贴到新建的文本文档中,点击左上角“文件”,再点击保存
5.关闭文本文档
6.双击打开
7.依次输入邮箱名称、刚刚获取到的授权码(不是密码)、起始时间和终止时间。每次输入完需要按enter
8.为新建的word命名,此处需要注意命名后需要手动在文件名后加上“.docx”,命名结束后单击enter。
9.等待结果输出即可,默认生成位置在当前文件夹。
# -*- coding: utf-8 -*-import imaplibimport emailfrom email.header import decode_headerfrom email.utils import parsedate_to_datetimeimport datetimefrom datetime import datetime as dtfrom bs4 import BeautifulSoupfrom docx import Documentimport sysimport os# ========== 解码邮件头(处理各种编码) ==========def decode_mime_header(header):if header is None:return""decoded_parts = []for part, encoding in decode_header(header):if isinstance(part, bytes):if encoding:try:part = part.decode(encoding, errors='ignore')except:part = part.decode('utf-8', errors='ignore')else:# 尝试常见编码for enc in ['utf-8', 'gbk', 'gb2312']:try:part = part.decode(enc)breakexcept:continueelse:part = part.decode('utf-8', errors='ignore')decoded_parts.append(part)return''.join(decoded_parts)# ========== 解码邮件正文内容 ==========def decode_payload(payload, charset):"""尝试多种编码解码邮件内容"""if not payload:return ""if charset:try:return payload.decode(charset, errors='ignore')except:passfor enc in ['utf-8', 'gbk', 'gb2312', 'big5', 'latin1']:try:return payload.decode(enc)except:continuereturn payload.decode('utf-8', errors='ignore')# ========== 提取邮件正文 ==========def extract_email_body(msg):"""提取邮件正文,支持多种编码"""body = ""if msg.is_multipart():for part in msg.walk():content_type = part.get_content_type()content_disposition = str(part.get("Content-Disposition"))if"attachment" in content_disposition:continueif content_type == "text/plain":payload = part.get_payload(decode=True)charset = part.get_content_charset()body = decode_payload(payload, charset)if body:breakelif content_type == "text/html"andnot body:payload = part.get_payload(decode=True)charset = part.get_content_charset()html = decode_payload(payload, charset)if html:soup = BeautifulSoup(html, 'html.parser')body = soup.get_text()else:content_type = msg.get_content_type()payload = msg.get_payload(decode=True)charset = msg.get_content_charset()text = decode_payload(payload, charset)if content_type == "text/plain":body = textelif content_type == "text/html":if text:soup = BeautifulSoup(text, 'html.parser')body = soup.get_text()return body.strip() if body else"(无正文)"# ========== 主函数:获取邮件并生成Word ==========def fetch_qq_mails(start_date, end_date, email_addr, password, output_file):imap_server = "imap.qq.com"try:print("正在连接QQ邮箱IMAP服务器...")mail = imaplib.IMAP4_SSL(imap_server)mail.login(email_addr, password)print("登录成功")mail.select("INBOX")print("已选择收件箱")# 获取所有邮件的IDprint("正在获取所有邮件ID...")typ, data = mail.search(None, 'ALL')if typ != 'OK':print("搜索邮件失败")returnall_msg_ids = data[0].split()total = len(all_msg_ids)print(f"收件箱共有 {total} 封邮件")if total == 0:print("收件箱为空")return# 用于存放符合条件的邮件IDselected_ids = []print(f"正在筛选日期范围 {start_date} 至 {end_date} 的邮件...")# 遍历所有邮件,只取头部解析日期for i, msg_id in enumerate(all_msg_ids, 1):# 每100封显示一次进度if i % 100 == 0or i == total:print(f"已检查 {i}/{total} 封邮件...")# 只获取邮件头部,不下载正文(速度快)typ, data = mail.fetch(msg_id, '(RFC822.HEADER)')if typ != 'OK':print(f" 获取邮件 {msg_id} 头部失败,跳过")continue# 解析头部中的日期raw_header = data[0][1]msg_header = email.message_from_bytes(raw_header)date_str = msg_header.get("Date", "")ifnot date_str:continuetry:date_obj = parsedate_to_datetime(date_str).date()except:# 日期解析失败,跳过这封continue# 判断日期是否在范围内if start_date <= date_obj <= end_date:selected_ids.append(msg_id)print(f"找到符合条件的邮件 {len(selected_ids)} 封")ifnot selected_ids:print("没有找到符合条件的邮件")return# 创建Word文档doc = Document()doc.add_heading(f'QQ邮箱收件箱邮件汇总 ({start_date} 至 {end_date})', level=1)doc.add_paragraph(f'导出时间:{dt.now().strftime("%Y-%m-%d %H:%M:%S")}')# 逐个处理符合条件的邮件(下载完整内容)for idx, msg_id in enumerate(selected_ids, 1):print(f"正在处理第 {idx}/{len(selected_ids)} 封邮件...")typ, data = mail.fetch(msg_id, '(RFC822)')if typ != 'OK':print(f" 获取邮件 {msg_id} 完整内容失败,跳过")continueraw_email = data[0][1]msg = email.message_from_bytes(raw_email)# 提取字段subject = decode_mime_header(msg.get("Subject", "无主题"))from_ = decode_mime_header(msg.get("From", "未知发件人"))date_str = msg.get("Date", "")try:date_obj_full = parsedate_to_datetime(date_str)date_display = date_obj_full.strftime("%Y-%m-%d %H:%M:%S")except:date_display = date_strbody = extract_email_body(msg)# 添加到Worddoc.add_heading(f"邮件 {idx}", level=2)doc.add_paragraph(f"发件人:{from_}")doc.add_paragraph(f"主题:{subject}")doc.add_paragraph(f"日期:{date_display}")doc.add_paragraph("正文:")doc.add_paragraph(body)doc.add_page_break()doc.save(output_file)print(f"汇总完成,结果已保存至:{output_file}")except imaplib.IMAP4.error as e:print(f"IMAP错误:{e}")print("请检查邮箱地址和授权码,确保已开启IMAP服务")except Exception as e:print(f"发生错误:{e}")finally:try:mail.close()mail.logout()except:pass# ========== 主入口 ==========def main():print("=== QQ邮箱邮件汇总工具(最终版) ===")email_addr = input("请输入QQ邮箱地址:").strip()password = input("请输入授权码(不是QQ密码):").strip()start_str = input("请输入起始日期(格式:YYYY-MM-DD):").strip()end_str = input("请输入结束日期(格式:YYYY-MM-DD):").strip()try:start_date = dt.strptime(start_str, "%Y-%m-%d").date()end_date = dt.strptime(end_str, "%Y-%m-%d").date()except ValueError:print("日期格式错误,请使用 YYYY-MM-DD 格式")input("按回车键退出...")sys.exit(1)if start_date > end_date:print("起始日期不能晚于结束日期")input("按回车键退出...")sys.exit(1)# 默认保存到桌面,避免权限问题desktop = os.path.join(os.path.expanduser("~"), "Desktop")default_name = "mail_summary.docx"user_input = input(f"请输入输出Word文件名(默认保存到桌面:{default_name}):").strip()ifnot user_input:output_file = os.path.join(desktop, default_name)else:# 如果用户输入了文件名,也保存到桌面output_file = os.path.join(desktop, user_input)print(f"文件将保存到:{output_file}")fetch_qq_mails(start_date, end_date, email_addr, password, output_file)input("程序执行完毕,按回车键退出...")if __name__ == "__main__":main()
夜雨聆风