导读:本期聚焦于小伙伴创作的《如何用Python通过imaplib协议获取邮件附件并自动化分类保存》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用Python通过imaplib协议获取邮件附件并自动化分类保存》有用,将其分享出去将是对创作者最好的鼓励。

日常办公中我们经常需要处理大量邮件附件,手动下载、分类、归档不仅耗时还容易出错。通过Python结合imaplib协议可以实现邮件附件的自动获取与分类保存,大幅降低重复工作量。

如何用Python通过imaplib协议获取邮件附件并自动化分类保存

准备工作

首先需要确保邮箱开启IMAP服务,不同邮箱的开启方式略有差异,一般在邮箱设置的账户安全选项中可以找到。同时需要记录邮箱的IMAP服务器地址和端口,比如常见邮箱的配置如下:

邮箱类型IMAP服务器地址端口
QQ邮箱imap.qq.com993
163邮箱imap.163.com993
Gmailimap.gmail.com993

另外需要安装Python内置的imaplibemail库,这两个库无需额外安装,Python环境自带。如果需要处理特定格式附件可能还需要额外安装对应库,比如处理PDF可以安装PyPDF2

连接邮箱服务器

使用imaplib建立SSL连接,登录邮箱账户,示例代码如下:

import imaplib
import email
from email.header import decode_header
import os

# 邮箱配置信息
EMAIL_USER = "your_email@ipipp.com"
EMAIL_PASSWORD = "your_email_password"  # QQ邮箱等需要使用授权码,不是登录密码
IMAP_SERVER = "imap.ipipp.com"
IMAP_PORT = 993

# 建立连接并登录
def connect_mailbox():
    try:
        # 创建SSL连接
        mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
        # 登录邮箱
        mail.login(EMAIL_USER, EMAIL_PASSWORD)
        print("邮箱登录成功")
        return mail
    except Exception as e:
        print(f"邮箱连接失败:{e}")
        return None

获取邮件附件

登录成功后选择收件箱,遍历邮件提取附件内容,需要注意处理邮件的编码问题,避免中文文件名乱码。

def get_attachments(mail):
    # 选择收件箱,只读模式
    mail.select("INBOX", readonly=False)
    # 搜索未读邮件,也可以根据需求修改搜索条件
    status, messages = mail.search(None, "UNSEEN")
    if status != "OK":
        print("搜索邮件失败")
        return []
    
    email_ids = messages[0].split()
    attachments = []
    
    for email_id in email_ids:
        # 获取邮件内容
        status, msg_data = mail.fetch(email_id, "(RFC822)")
        if status != "OK":
            continue
        
        # 解析邮件
        raw_email = msg_data[0][1]
        msg = email.message_from_bytes(raw_email)
        
        # 获取发件人信息
        from_addr = ""
        from_header = msg.get("From")
        if from_header:
            from_parts = decode_header(from_header)
            for part in from_parts:
                if isinstance(part[0], bytes):
                    from_addr += part[0].decode(part[1] if part[1] else "utf-8")
                else:
                    from_addr += part[0]
        
        # 遍历邮件所有部分,提取附件
        for part in msg.walk():
            content_disposition = part.get("Content-Disposition", "")
            if "attachment" in content_disposition or "filename" in content_disposition:
                # 获取附件文件名
                filename_header = part.get_filename()
                if filename_header:
                    # 解码文件名
                    filename_parts = decode_header(filename_header)
                    filename = ""
                    for f_part in filename_parts:
                        if isinstance(f_part[0], bytes):
                            filename += f_part[0].decode(f_part[1] if f_part[1] else "utf-8")
                        else:
                            filename += f_part[0]
                    
                    # 获取附件内容
                    file_data = part.get_payload(decode=True)
                    if file_data:
                        attachments.append({
                            "filename": filename,
                            "data": file_data,
                            "from_addr": from_addr,
                            "email_id": email_id.decode()
                        })
    return attachments

自动化分类保存附件

根据附件的文件后缀、发件人等规则,将附件保存到不同的本地目录,示例分类规则为:按文件类型分类,同时发件人单独建立子目录。

def classify_and_save(attachments, save_root_dir):
    # 确保根目录存在
    if not os.path.exists(save_root_dir):
        os.makedirs(save_root_dir)
    
    for att in attachments:
        filename = att["filename"]
        file_data = att["data"]
        from_addr = att["from_addr"]
        
        # 提取文件后缀
        file_ext = os.path.splitext(filename)[1].lower()
        # 按文件类型分类目录
        type_dir_map = {
            ".pdf": "PDF文件",
            ".doc": "Word文件",
            ".docx": "Word文件",
            ".xls": "Excel文件",
            ".xlsx": "Excel文件",
            ".jpg": "图片文件",
            ".png": "图片文件",
            ".txt": "文本文件"
        }
        type_dir = type_dir_map.get(file_ext, "其他文件")
        
        # 提取发件人邮箱前缀作为子目录名
        from_user = from_addr.split("@")[0] if "@" in from_addr else "未知发件人"
        # 清理目录名中的特殊字符
        from_user = "".join(c for c in from_user if c not in r'/:*?"<>|')
        
        # 构建保存路径
        save_dir = os.path.join(save_root_dir, type_dir, from_user)
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
        
        # 保存文件
        save_path = os.path.join(save_dir, filename)
        with open(save_path, "wb") as f:
            f.write(file_data)
        print(f"附件保存成功:{save_path}")

完整执行流程

将上面的函数组合起来,实现完整的邮件附件获取、分类、保存流程,还可以添加标记已读、异常处理等逻辑。

def main():
    # 本地保存根目录
    SAVE_ROOT_DIR = "./邮件附件归档"
    
    # 连接邮箱
    mail = connect_mailbox()
    if not mail:
        return
    
    try:
        # 获取附件
        attachments = get_attachments(mail)
        if not attachments:
            print("未找到符合条件的附件")
            return
        
        print(f"共找到{len(attachments)}个附件")
        # 分类保存
        classify_and_save(attachments, SAVE_ROOT_DIR)
        
        # 可选:标记邮件为已读
        # mail.select("INBOX")
        # for att in attachments:
        #     mail.store(att["email_id"], "+FLAGS", "\Seen")
        
        # 关闭连接
        mail.close()
        mail.logout()
        print("邮箱连接已关闭")
    except Exception as e:
        print(f"处理过程出错:{e}")
        if mail:
            mail.close()
            mail.logout()

if __name__ == "__main__":
    main()

常见问题处理

  • 登录失败:如果是QQ邮箱、163邮箱等,需要使用邮箱的授权码而不是登录密码,授权码在邮箱设置中生成。
  • 附件文件名乱码:使用email.header.decode_header方法解码,适配不同编码格式的邮件头。
  • 大附件处理:如果附件体积过大,建议分块读取,避免内存占用过高,也可以添加附件大小过滤规则,跳过超大附件。
  • 连接超时:可以添加重试机制,当连接失败时自动重试几次,提升脚本的稳定性。

Pythonimaplib邮件附件自动化分类修改时间:2026-07-16 09:21:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。