当前位置: 首页 > article >正文

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.lryc.cn/news/2384668.html

相关文章:

  • 什么是VR场景?VR与3D漫游到底有什么区别
  • python学习day2:进制+码制+逻辑运算符
  • 【分布式文件系统】FastDFS
  • 14、自动配置【源码分析】-初始加载自动配置类
  • word为章节标题添加自动编号
  • 无人机飞行间隔安全智能评估、安全风险评估
  • C++成员对象和封闭类
  • 【VLNs篇】03:VLMnav-端到端导航与视觉语言模型:将空间推理转化为问答
  • PCB设计实践(二十五)贴片电阻与插件电阻的全面解析:差异、演进与应用场景
  • 知道不知道
  • 文章记单词 | 第106篇(六级)
  • SpringBoot项目中Redis的使用
  • Canvas设计图片编辑器全讲解(一)Canvas基础(万字图文讲解)
  • 利用Qt绘图随机生成带多种干扰信息的数字图片
  • STM32——从点灯到传感器控制
  • java day14
  • Tailwind css实战,基于Kooboo构建AI对话框页面(一)
  • 重塑数学边界:人工智能如何引领数学研究的新纪元
  • docker部署并测试翻译模型-CSANMT连续语义增强机器翻译
  • 蓝桥杯2025.5.23每日一题-儿童数
  • Spring Boot项目配置核心 - pom.xml的依赖管理与构建优化
  • 告别手抖困扰:全方位健康护理指南
  • 图解深度学习 - 特征工程(DL和ML的核心差异)
  • 《短线操盘跟庄关键技术》速读笔记
  • Datacom-hcia~Datacom-hcie学习笔记索引
  • Oracle 中 SHRINK 与 MOVE 操作的比较
  • 受不了github的网络限制了,我开源了一个图床工具 gitee-spring-boot-starter
  • 【Python 基础与实战】从基础语法到项目应用的全流程解析
  • 2025年医美行业报告60+份汇总解读 | 附 PDF 下载
  • API自动化与持续集成核心实战知识点!