Python编程:email模块+smtplib模块+poplib模块实现邮件收取和发送

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: Python编程:email模块+smtplib模块+poplib模块实现邮件收取和发送

发送邮件


# email负责构造邮件,smtplib负责发送邮件
from email import encoders
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import os
import smtplib
class EmailSender(object):
    def __init__(self, from_addr, password, server="smtp.163.com", port=25):
        # 发信人账号密码
        self.from_addr = from_addr
        self.password = password
        # 收件人地址
        self.to_addrs = []
        # SMTP服务器地址
        self.smtp_server = server
        self.smtp_port = port
        self.msg =self._get_email()
        self._add_sender(self.from_addr)
    # 添加标题
    def set_header(self, text):
        self.msg['Subject'] = Header(text, 'utf-8').encode()
    # 添加文本
    def add_text(self, text):
        self._add_content(text, "plain")
    # 添加邮件(优先)
    def add_html(self, html):
        self._add_content(html, "html")
    # 增加邮件地址
    def add_receiver(self, address):
        # msg['To'] 接收的是字符串而不是list,如果有多个邮件地址,用,分隔即可
        self.to_addrs.append(address)
    # 增加多个邮件地址
    def add_receivers(self, addresses):
        self.to_addrs.extend(addresses)
    # 添加附件
    def add_attach(self, fullname):
        # 加上一个MIMEBase,从本地读取一个图片:
        filename = os.path.basename(fullname)
        with open(fullname, 'rb') as f:
            # 设置附件的MIME和文件名,这里是png类型:
            name, ext = os.path.splitext(filename)
            ext = ext.strip(".")
            mime = MIMEBase('image', ext, filename=filename)
            # 加上必要的头信息:
            mime.add_header('Content-Disposition', 'attachment', filename=filename)
            mime.add_header('Content-ID', '<0>')
            mime.add_header('X-Attachment-Id', '0')
            # 把附件的内容读进来:
            mime.set_payload(f.read())
            # 用Base64编码:
            encoders.encode_base64(mime)
            # 添加到MIMEMultipart:
            self.msg.attach(mime)
    # 发送
    def send(self):
        self._add_receivers()
        server = smtplib.SMTP(self.smtp_server, self.smtp_port)  # SMTP协议默认端口是25
        # server.set_debuglevel(1)  # 打印出和SMTP服务器交互的所有信息
        server.login(self.from_addr, self.password)
        server.sendmail(self.from_addr, self.to_addrs, self.msg.as_string())
        server.quit()
    # 邮件对象添加内容
    def _add_content(self, text, text_type):
        # 'plain'表示纯文本, 'html'表示html文本,utf-8编码保证多语言兼容性
        self.msg.attach(MIMEText(text, text_type, 'utf-8'))
    # 格式化一个邮件地址
    def _format_addr(self, s):
        # 如果包含中文,需要通过Header对象进行编码
        name, addr = parseaddr(s)
        return formataddr((Header(name, 'utf-8').encode(), addr))
    # 获取邮件对象
    def _get_email(self):
        # 同时支持HTML和Plain格式
        return  MIMEMultipart("alternative")
    # 邮件对象添加发送者
    def _add_sender(self, from_addr):
        self.msg['From'] = self._format_addr('%s <%s>'% (from_addr, from_addr))
    # 邮件对象添加收件人
    def _add_receivers(self):
        addrs = [self._format_addr('%s <%s>' % (addr, addr)) for addr in self.to_addrs]
        self.msg['To'] = ",".join(addrs)
if __name__ == '__main__':
    email = EmailSender("xxx@163.com", "xxx")
    email.set_header("你好")
    email.add_text("hello1")
    email.add_text("hello2")
    # email.add_attach("images/guilunmei.jpeg")
    # email.add_attach("images/guilunmei.jpeg")
    email.add_receiver("mouday@qq.com")
    email.add_receiver("xxx@qq.com")
    email.send()

接收邮件

# poplib模块负责接收, email模块负责解析
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import poplib
class EmailReceiver(object):
    def __init__(self, email, password, server="pop.163.com"):
    # 输入邮件地址, 口令和POP3服务器地址:
        self.email = email
        self.password = password
        self.pop3_server = server
        self._connect()
        self.message = {
            "From": None,
            "To": None,
            "Subject": None,
            "text": [],
            "attachment": []
        }  # 解析后的邮件内容
    # stat()返回邮件数量和占用空间:
    def get_stat(self):
        return self.server.stat()
    # list()返回所有邮件的编号:
    def get_list(self):
        resp, mails, octets = self.server.list()
        # 可以查看返回的列表类似[b'1 82923', b'2 2184', ...]
        return mails
    # 获取一封邮件
    def get_email(self, index):
        self._get_email(index)
        return self.message
    # 获取最新一封邮件, 注意索引号从1开始:
    def get_last_email(self):
        index = len(self.get_list())
        return self.get_email(index)
    # 连接到POP3服务器:
    def _connect(self):
        self.server = poplib.POP3(self.pop3_server)
        # 身份认证:
        self.server.user(self.email)
        self.server.pass_(self.password)
    # 可以打开或关闭调试信息:
    # server.set_debuglevel(1)
    def _get_welcome(self):
        # 可选:打印POP3服务器的欢迎文字:
        return self.server.getwelcome().decode('utf-8')
    # 获取一封邮件
    def _get_email(self, index):
        resp, lines, octets = self.server.retr(index)
        # lines存储了邮件的原始文本的每一行,
        # 可以获得整个邮件的原始文本:
        msg_content = b'\r\n'.join(lines).decode('utf-8')
        # 稍后解析出邮件:
        msg = Parser().parsestr(msg_content)
        # 可以根据邮件索引号直接从服务器删除邮件:
        # server.dele(index)
        return self._get_email_content(msg)
    def __del__(self):
        # 关闭连接:
        self.server.quit()
    # 解码
    def _decode_str(self, s):
        value, charset = decode_header(s)[0]
        if charset:
            value = value.decode(charset)
        return value
    # 获取编码
    def _guess_charset(self, msg):
        charset = msg.get_charset()
        if charset is None:
            content_type = msg.get('Content-Type', '').lower()
            pos = content_type.find('charset=')
            if pos >= 0:
                charset = content_type[pos + 8:].strip()
        return charset
    # 解析邮件 indent用于缩进显示:
    def _parse_email(self, msg, indent=0):
        if indent == 0:
            for header in ['From', 'To', 'Subject']:
                value = msg.get(header, '')
                if value:
                    if header == 'Subject':
                        value = self._decode_str(value)
                    else:
                        hdr, addr = parseaddr(value)
                        name = self._decode_str(hdr)
                        value = u'%s <%s>' % (name, addr)
                self.message[header] = value
        if (msg.is_multipart()):
            parts = msg.get_payload()
            for n, part in enumerate(parts):
                self._parse_email(part, indent + 1)
        else:
            content_type = msg.get_content_type()
            if content_type == 'text/plain' or content_type == 'text/html':
                content = msg.get_payload(decode=True)
                charset = self._guess_charset(msg)
                if charset:
                    content = content.decode(charset)
                self.message["text"].append(content)
            else:
                self.message["attachment"].append(content_type)
    # 获取邮件内容
    def _get_email_content(self, msg):
        self._parse_email(msg)
        return self.message
if __name__ == '__main__':
    email = EmailReceiver("xxx@163.com", "xxx")
    msg = email.get_last_email()
    print(msg)

相关文章
|
2月前
|
SQL 关系型数据库 数据库
Python SQLAlchemy模块:从入门到实战的数据库操作指南
免费提供Python+PyCharm编程环境,结合SQLAlchemy ORM框架详解数据库开发。涵盖连接配置、模型定义、CRUD操作、事务控制及Alembic迁移工具,以电商订单系统为例,深入讲解高并发场景下的性能优化与最佳实践,助你高效构建数据驱动应用。
313 7
|
2月前
|
Python
Python编程:运算符详解
本文全面详解Python各类运算符,涵盖算术、比较、逻辑、赋值、位、身份、成员运算符及优先级规则,结合实例代码与运行结果,助你深入掌握Python运算符的使用方法与应用场景。
180 3
|
2月前
|
数据处理 Python
Python编程:类型转换与输入输出
本教程介绍Python中输入输出与类型转换的基础知识,涵盖input()和print()的使用,int()、float()等类型转换方法,并通过综合示例演示数据处理、错误处理及格式化输出,助你掌握核心编程技能。
436 3
|
2月前
|
JSON 算法 API
Python中的json模块:从基础到进阶的实用指南
本文深入解析Python内置json模块的使用,涵盖序列化与反序列化核心函数、参数配置、中文处理、自定义对象转换及异常处理,并介绍性能优化与第三方库扩展,助你高效实现JSON数据交互。(238字)
364 4
|
2月前
|
并行计算 安全 计算机视觉
Python多进程编程:用multiprocessing突破GIL限制
Python中GIL限制多线程性能,尤其在CPU密集型任务中。`multiprocessing`模块通过创建独立进程,绕过GIL,实现真正的并行计算。它支持进程池、队列、管道、共享内存和同步机制,适用于科学计算、图像处理等场景。相比多线程,多进程更适合利用多核优势,虽有较高内存开销,但能显著提升性能。合理使用进程池与通信机制,可最大化效率。
267 3
|
2月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
268 0
|
2月前
|
XML JSON 数据处理
超越JSON:Python结构化数据处理模块全解析
本文深入解析Python中12个核心数据处理模块,涵盖csv、pandas、pickle、shelve、struct、configparser、xml、numpy、array、sqlite3和msgpack,覆盖表格处理、序列化、配置管理、科学计算等六大场景,结合真实案例与决策树,助你高效应对各类数据挑战。(238字)
182 0
|
API Python
Python邮箱API发送邮件的方法和步骤
使用Python发送邮件涉及导入smtplib和email模块,设置发件人、收件人、主题和内容,然后连接SMTP服务器(如示例中的smtp.example.com)并使用SMTP方法发送。完整代码示例包括异常处理,确保邮件发送成功或提供错误信息。通过这种方式,可以实现Python的自动化邮件发送功能。
|
数据安全/隐私保护 Python
Python 技术篇-连接qq邮箱服务器,调用qq邮箱发送邮件实战演示,qq邮箱授权码开通方法
Python 技术篇-连接qq邮箱服务器,调用qq邮箱发送邮件实战演示,qq邮箱授权码开通方法
1114 0
Python 技术篇-连接qq邮箱服务器,调用qq邮箱发送邮件实战演示,qq邮箱授权码开通方法
|
Web App开发 Python
python发送各类邮件的主要方法
python中email模块使得处理邮件变得比较简单,今天着重学习了一下发送邮件的具体做法,这里写写自己的的心得,也请高手给些指点。     一、相关模块介绍     发送邮件主要用到了smtplib和email两个模块,这里首先就两个模块进行一下简单的介绍:    1、smtplib模块       smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])    SMTP类构造函数,表示与SMTP服务器之间的连接,通过这个连接可以向smtp服务器发送指令,执行相关操作(如:登陆、发送邮件)。
1096 0

推荐镜像

更多