Python邮件处理:POP与SMTP

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 Exceptioncontent = 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_headerdef 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'] = frommessage['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 smtplibdef 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.pswp.cn/diannao/84128.shtml

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

相关文章

IP风险度自检,多维度守护网络安全

如今IP地址不再只是网络连接的标识符,更成为评估安全风险的核心维度。IP风险度通过多维度数据建模,量化IP地址在网络环境中的安全威胁等级,已成为企业反欺诈、内容合规、入侵检测的关键工具。据Gartner报告显示,2025年全球78%的企…

Flink集成资源管理器

Flink集成资源管理器 Apache Flink 支持多种资源管理器,主要包括以下几种‌: YARN ResourceManager ‌:适用于使用 Hadoop YARN 作为资源管理器的环境。YARN ResourceManager 负责管理集群中的资源,包括 CPU、内存等,并…

upload 文件上传审计

目录 LOW Medium HIgh Impossible 概述 很多Web站点都有文件上传的接口(比如注册时上传头像等),由于没有对上传的文件类型进行严格限制,导致可以上传一些文件(比如Webshell)。 上传和SQL、XSS等都是主流…

【freertos-kernel】list

freertos list 基本类型结构体ListItem_t (list.h)List_t (list.h) 宏函数函数vListInitialisevListInitialiseItemvListInsertEndvListInsertuxListRemove 基本类型 freertos为了兼容性,重新定义了基本类型&#xff…

游戏盾的功有哪些?

游戏盾的功能主要包括以下几方面: 一、网络攻击防护 DDoS攻击防护: T级防御能力:游戏盾提供分布式云节点防御集群,可跨地区、跨机房动态扩展防御能力和负载容量,轻松达到T级别防御,有效抵御SYN Flood、UD…

PycharmFlask 学习心得:路由(3-4)

对路由的理解: 用户输入网址 例如:http://localhost:5000/hello 浏览器会向这个地址发起一个 HTTP 请求(比如 GET 请求) 请求到达 Flask 的服务器 Flask 监听着某个端口(如 5000),收到请求后…

课程与考核

6.1 课程讲解与实战考核 6.1.1 SQL注入篇考核 考核目标:通过手动注入与工具结合,获取目标数据库敏感信息。 题目示例: 目标URL:http://vuln-site.com/product?id1 要求: 判断注入类型(联合查询/报错注…

线程池介绍,分类,实现(工作原理,核心组成,拒绝策略),固态线程池的实现+详细解释(支持超时取消机制和不同的拒绝策略)

目录 线程池 介绍 分类 实现 工作原理 核心组成 拒绝策略 固态线程池 功能 std::future 实现 拒绝策略支持 提交任务 超时取消 用户检测取消 安全销毁 代码 测试 线程池 介绍 线程池(图解,本质,模拟实现代码),添加单例模式(懒汉思路代码)_线程池单例-CSDN博…

纺线机与PLC通讯故障?ETHERCAT/CANopen网关秒解协议难题

在纺织行业智能化转型浪潮中,设备间高效通信是实现自动化生产的关键。JH-ECT009疆鸿智能EtherCAT转CANopen协议转换网关,凭借出色的协议适配能力,成功架起倍福PLC与自动纺线机间的通信桥梁,为纺织厂自动化生产注入强劲动力。 纺织…

深度剖析并发I/O模型select、poll、epoll与IOCP核心机制

核心概要:select、poll、epoll 和 IOCP 是四种用于提升服务器并发处理能力的I/O模型或机制。前三者主要属于I/O多路复用范畴,允许单个进程或线程监视多个I/O流的状态;而 IOCP 则是一种更为彻底的异步I/O模型。 一、引言:为何需要这…

microsoft中word如何添加个人签名

https://support.microsoft.com/zh-cn/office/%E6%8F%92%E5%85%A5%E7%AD%BE%E5%90%8D-f3b3f74c-2355-4d53-be89-ae9c50022730 插入签名图片 图片格式选择裁剪合适的大小 使用的签名如果不是白色纸张的话可以重新着色 依次点击图片格式——颜色——重新着色——黑白50% 设置透…

linux初识--基础指令

Linux下基础指令 ls 指令 语法: ls [ 选项 ] [ ⽬录或⽂件 ] 功能:对于⽬录,该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件,将列出⽂件名以及其他信 息。 常⽤选项: -a 列出⽬录下的所有⽂件,包括以…

实战:Dify智能体+Java=自动化运营工具!

我们在运营某个圈子的时候,可能每天都要将这个圈子的“热门新闻”发送到朋友圈或聊天群里,但依靠传统的实现手段非常耗时耗力,我们通常要先收集热门新闻,再组装要新闻内容,再根据内容设计海报等。 那怎么才能简化并高…

RabbitMQ可靠传输——持久性、发送方确认

一、持久性 前面学习消息确认机制时,是为了保证Broker到消费者直接的可靠传输的,但是如果是Broker出现问题(如停止服务),如何保证消息可靠性?对此,RabbitMQ提供了持久化功能: 持久…

(Java基础笔记vlog)Java中常见的几种设计模式详解

前言: 在 Java 编程里,设计模式是被反复使用、多数人知晓、经过分类编目的代码设计经验总结。他能帮助开发者更高效地解决常见问题,提升代码的可维护性、可扩展性和复用性。下面介绍Java 中几种常见的设计模式。 单例模式(Singlet…

(8)Spring Boot 原生镜像支持

Spring Boot 原生镜像支持 👉 点击展开题目 在Spring Boot 3.x中,如何设计一个支持GraalVM原生镜像的微服务?需要特别注意哪些限制? 📌 Spring Boot 3.x 原生镜像概述 Spring Boot 3.x 通过 Spring Native 项目提供了对 GraalVM 原生镜像的一流支持,使开发者能够将 S…

不使用SOAP,从PDF表单连接数据库

不使用SOAP协议,通过XFDF格式实现PDF表单与数据库交互的方法。该方法兼容免费的Adobe Reader,且无需特殊权限设置。 背景与问题 历史方案: Adobe曾提供ADBC接口(基于ODBC),但在Acrobat 9后被移除。SOAP方案在免费版Rea…

HTTP由浅入深

文章目录 概述特点URL HTTP 与 HTTPS概述HTTP 工作原理HTTPS 的作用区别总结 请求报文请求行常见请求方法请求头请求体Content-Type 详解常见场景 Content-Type 对应关系 响应报文响应行状态码详解1xx:信息响应(Informational)2xx&#xff1a…

Redis淘汰策略

Redis有八种淘汰策略 noeviction :不进行淘汰,直接报错。allkeys-lru :随机淘汰最久未使用的键。volatile-lru :从设置了过期时间的键中,随机淘汰最久未使用的键。allkeys-random :随机淘汰某个键。volati…

Maven打包SpringBoot项目,因包含SpringBootTest单元测试和Java预览版特性导致打包失败

SpringBoot启用Java预览版特性&#xff08;无测试类&#xff09; 在pom.xml文件中加入以下配置表示启用Java预览版 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration>…