Python邮件处理:POP与SMTP

news2025/5/24 14:38:30

poplib简介

poplib 是Python 3中的官方邮件库,实现了POP的标准:RFC1939,用于邮件的收取。与之类似的还有imaplib 。

(注:本文仅拿pop举例)

poplib的使用方法,就是几步:

  1. 先创建一个poplib.POP3类的实例(如果使用SSL,则是poplib.POP3_SSL类的实例)
  2. 之后使用userpass_设置认证
  3. 再使用list获取邮件列表
  4. 根据列表序号,使用retr收取邮件。
  5. (可选)使用delete删除邮件。

另外,如果需要调试,可以使用类的set_debug方法,打印详细的报文交互过程。

如:

def get_mail(host, port, is_ssl, is_debug, username, password):
    if is_ssl:
        server = poplib.POP3_SSL(host, port)

    else:
        server = poplib.POP3(host, port)

    # 开启debug模式,将会打印详细的报文交互过程,便于调试
    server.set_debuglevel(is_debug)
    if is_debug:
        print(server.getwelcome().decode('utf-8'))

    server.user(username)
    server.pass_(password)
    if is_debug:
        print('Messages: %s. Size: %s' % server.stat())

    resp, mails, octets = server.list()
    if is_debug:
        print(mails)

    for index in range(1, len(mails) + 1, 1):
        # 下文将自定义自定义函数,收取邮件
        if get_mail(server, index):
            server.dele(index)

解析邮件为EmailMessage

解析邮件的时候,可以使用Python 3的email 库。

我们使用email的parser.Parser类实例,把邮件内容解析成一个message.EmailMessage实例。

如:

def get_mail(server, index):
    resp, lines, octets = server.retr(index)
    if resp != b'+OK':
        raise Exception


    content = b'\r\n'.join(lines).decode('utf-8')
    msg = Parser().parsestr(content)
    return msg

获取邮件中的附件

如果我们需要获取邮件中的附件,可以进一步解析EmailMessage。

解析EmailMessage的时候,需要注意有的邮件文本也是以附件形式放入邮件中的。所以,需要判断附件的名字是不是message。

正文的文本有可能使用了非ASCII的编码,可以通过EmailMessage的get_charset方法取得。如果取得失败,再通过ContentType域取得。

def guess_charset(msg):  
    charset = msg.get_charset()    
    if charset:  
        return charset  
  
    content_type = msg.get('Content-Type', '').lower()  
    pos = content_type.find('charset=')
    if pos >= 0:
        remain = content_type[pos + 8:].strip()  
        pos = remain.find(';')  
        if pos >= 0:  
            return remain[:pos]  
  
        return remain  
  
    return None

最后完整的解析代码如下:

from email.utils import parseraddr
from email.header import decode_header

def save_attachment(path, msg):
    content_type = msg.get_content_type()
    content = msg.get_payload(decode=True)
    if content_type == 'text/plain' or content_type == 'text/html':
        charset = guess_charset(msg)
        if charset:
            content = content.decode(charset)

        else:
            content = content.decode('utf-8')

    with open(path) as fp:
        fp.write(content)

def parse_message(msg)
    # 获取邮件主题
    subject = msg.get('Subject', '')
    # 获取发件人
    from_value, from_addr = parseaddr(msg.get('From', ''))
    # 获取收件人
    to_value, to_addr = parseaddr(msg.get('To', ''))
    
    # 判断是否有附件
    if msg.is_multipart():
        parts = msg.get_payload()
        for n, part in enumerate(parts):
            name = part.get_filename('message')
            if name == 'message':
                save_attachment('message', part)

            else:
                realname = decode_str(name)
                attapath = os.path.join(attachments_path, realname)
                save_attachment(attapath, part)

    else:
        save_attachment('message', msg)

使用smtplib发送邮件

发送邮件相对来说比收取简单,因为格式我们可以控制,只要采用最简单标准的就行了。

先生成一个EmailMessage。

def generate_message(subject, from, to, message, attchment_list):
    if len(attchment_list) == 0:
        message = MIMEText(message, 'plain', 'gb2312')

    else:
        message = MIMEMultipart()
        message.attach(MIMEText(message, 'plain', 'gb2312'))

    message['Subject'] = Header(subject, 'gb2312')
    message['From'] = from
    message['To'] = to

    # attachment_list,是一个列表,每一项是一个包含Content-Type与路径的字典。
    for att in attachment_list:
        add_attachment(message, att['content-type'], att['path'])

    return message

追加附件的实现如下:

def add_attachment(message, contenttype, path):
    # Content-Type一般是text/html这种格式
    appname, subtype = contenttype.split('/')
    
    # 取得文件名作为附件里文件的名字,加入附件EmailMessage的Header
    _dirname, basename = os.path.split(path)
    encodedname = Header(basename, 'gb2312').encode()
    att = MIMEBase(appname, subtype, name=encodedname)
    att.add_header('Content-Disposition', 'attachment', filename=encodedname)

    # 加入附件内容
    att.set_payload(open(path, 'rb').read(), 'base64')

    message.attach(att)

使用smtplib发送的过程,类似与poplib。

  1. 创建一个SMTP(或者SMTP_SSL)实例
  2. 连接服务端(connect)
  3. 登录服务端(login)
  4. 发送邮件(sendmail)
import smtplib

def smtp_send(host, port, is_ssl, username, password, sender, receivers, message):
    if is_ssl:
        server = smtplib.SMTP_SSL()

    else:
        server = smtplib.SMTP()

    server.connect(host=host, port=port)
    server.login(username, password)
    server.sendmail(sender, receivers, message.as_string())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2384668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是VR场景?VR与3D漫游到底有什么区别

在数字化时代,虚拟现实(Virtual Reality, 简称VR)场景与3D漫游作为两种前沿技术,改变着人们的生活方式和体验模式。通过计算机模拟真实或假想的场景,让用户仿佛身临其境,并能与虚拟环境进行互动。尽管VR场景…

python学习day2:进制+码制+逻辑运算符

进制 Python 中的进制表示与转换 进制的基本概念 二进制、八进制、十进制、十六进制的定义与特点不同进制在计算机科学中的应用场景 Python 中的进制表示 二进制表示:使用 0b 前缀八进制表示:使用 0o 前缀十六进制表示:使用 0x 前缀示例…

【分布式文件系统】FastDFS

1.简介 讲这个之前,相信很多人特别是学java的,肯定在做苍穹外卖的时候肯定接触过一个东西,叫做阿里云OSS,他们的功能都差不多,但是阿里云的这个是要付费的,而FastDFS是免费开源的,是由淘宝资深…

word为章节标题添加自动编号

问题: 如何为word文档中的多级标题添加自动编号? 方法: 1、首先为文档各级标题设置格式样式,一级标题使用样式中的“标题 1”,二级标题使用“标题 2”,三级使用“标题 3”,也就是直接在开始—…

无人机飞行间隔安全智能评估、安全风险评估

无人机空中安全飞行评估需结合改进碰撞模型、蒙特卡洛仿真、安全间隔反推及动态避障策略,通过多机型分类与实时数据融合,实现从理论建模到实际部署的全流程管控,为城市低空密集飞行提供安全保障。 需求 无人机飞行间隔安全智能评估 无人机…

【VLNs篇】03:VLMnav-端到端导航与视觉语言模型:将空间推理转化为问答

栏目内容论文标题End-to-End Navigation with Vision-Language Models: Transforming Spatial Reasoning into Question-Answering (端到端导航与视觉语言模型:将空间推理转化为问答)核心问题如何利用大型视觉语言模型(VLM)实现端到端的机器人…

PCB设计实践(二十五)贴片电阻与插件电阻的全面解析:差异、演进与应用场景

一、基础结构与技术原理差异 物理结构差异 贴片电阻(SMD Resistor)采用表面贴装技术(SMT),其主体为扁平长方体或圆柱形结构,两端金属化电极直接与PCB焊盘接触。典型封装尺寸包括0402(1.00.5mm&a…

Canvas设计图片编辑器全讲解(一)Canvas基础(万字图文讲解)

一、前序 近两年AI发展太过迅速,各类AI产品层出不穷,AI绘图/AI工作流/AI视频等平台的蓬勃发展,促使图片/视频等复杂内容的创作更加简单,让更多普通人有了图片和视频创作的机会。另一方面用户内容消费也逐渐向图片和视频倾斜。在“…

利用Qt绘图随机生成带多种干扰信息的数字图片

背景 在学习AutoML或ML的过程中,需要一些图片类型的数据做分类预测训练,于是想到尝试最简单的数字识别,且单个数字的识别,也就是y的取值只有10种可能,即0到9。 以下参考代码分别考虑了数字字体的大小、数字颜色的深浅…

STM32——从点灯到传感器控制

STM32基础外设开发:从点灯到传感器控制 一、前言 本篇文章总结STM32F10x系列基础外设开发实例,涵盖GPIO控制、按键检测、传感器应用等。所有代码基于标准库开发,适合STM32初学者参考。 二、硬件准备 STM32F10x系列开发板LED模块有源蜂鸣器…

java day14

接昨天,响应 响应 就是我们在处理请求的时候,里面的return 其实方法里面写的return的返回平常的什么字符串啊什么等等;这些东西都是直接返回;如果是一个对象的话,我们会按json的格式返回; 这些都依赖于一…

Tailwind css实战,基于Kooboo构建AI对话框页面(一)

在当今数字化时代,AI 助手已成为网站和应用不可或缺的一部分。本文将带你一步步使用 Tailwind CSS 和 Kooboo 构建一个现代化的 AI 对话界面框。 一、选择 Kooboo平台 的核心优势 智能提示:在输入 class 属性时,会自动触发 Tailwind CSS 规则…

重塑数学边界:人工智能如何引领数学研究的新纪元

目录 一、人工智能如何重新定义数学研究的边界 (一)数学与AI的关系:从基础理论到创新思维的回馈 (二)AI的创造力:突破传统推理的局限 (三)AI对数学研究的潜在贡献:创…

docker部署并测试翻译模型-CSANMT连续语义增强机器翻译

1.模型选择CSANMT-Translation模型: 2.修改docker-compose.yml文件,重新定义模型缓存路径和存储路径 其中MODELSCOPE_CACHE指定了模型的下载路径。 3.运行docker compose up -d --build,提示出现报错:Error response from daemon…

Spring Boot项目配置核心 - pom.xml的依赖管理与构建优化

基础架构 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVe…

告别手抖困扰:全方位健康护理指南

手抖&#xff0c;医学上称为震颤&#xff0c;是常见的身体症状&#xff0c;可能由多种原因引发&#xff0c;了解其成因并采取科学护理措施&#xff0c;对改善症状、维护健康至关重要。 生理性手抖往往因情绪激动、过度劳累、大量饮用咖啡或酒精等引起&#xff0c;这种手抖通常较…

图解深度学习 - 特征工程(DL和ML的核心差异)

前言 深度学习通过自动化特征提取&#xff0c;简化了机器学习工作流程&#xff0c;它让解决问题变得更加简单。因为深度学习将特征工程完全自动化&#xff0c;而特征工程曾经是机器学习工作流程中最关键的一步。 一、机器学习特征工程 机器学习为什么需要特征工程&#xff08…

Datacom-hcia~Datacom-hcie学习笔记索引

hcia VLAN工作原理实验案例(超详细)https://blog.csdn.net/Fanmeang/article/details/145855768?spm1001.2014.3001.5502 交换机工作原理实验案例https://blog.csdn.net/Fanmeang/article/details/145802382?spm1001.2014.3001.5502 ARP理论实验案例&#xff08;超详细&am…

受不了github的网络限制了,我开源了一个图床工具 gitee-spring-boot-starter

嗨嗨嗨~ 我老马又又来了&#xff01;&#xff01;&#xff01;上次写了一篇我开源了一款阿里云OSS的spring-boot-starter&#xff0c;然后买的资源包到期了&#xff0c;后面又想白&#xff08;开&#xff09;嫖&#xff08;源&#xff09;的路子&#xff0c;首先想到了使用gith…

2025年医美行业报告60+份汇总解读 | 附 PDF 下载

原文链接&#xff1a;https://tecdat.cn/?p42122 医美行业在消费升级与技术迭代的双重驱动下&#xff0c;已从边缘市场逐步走向主流。数据显示&#xff0c;2024 年中国医美市场规模突破 3000 亿元&#xff0c;年复合增长率达 15%&#xff0c;但行业仍面临正品率不足、区域发展…