python操作邮箱发送邮件和接收邮件

首先,用到的模块

import logging
import traceback
from email.mime.application import MIMEApplication
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.utils import formataddr
from email.mime.text import MIMEText
from poplib import POP3
from email.header import decode_header
from email.parser import Parser
from email.utils import parseaddr

发送带附件的邮件

def send(email_title, content, filepath, receiver_filename, receiver, smtpserver='smtp.mxhichina.com',
         nick_name='开发者账号', sender, my_pass, del_file=True):
    print("开始发送邮件........")
    try:
        # 创建一个带附件的实例
        msg = MIMEMultipart()
        msg['From'] = formataddr([nick_name, sender])
        msg['To'] = ','.join(receiver)
        msg['Subject'] = email_title
        msg.attach(MIMEText(content, 'plain', 'utf-8'))  # 邮件正文内容

        xlsxpart = MIMEApplication(open(filepath, 'rb').read())
        xlsxpart.add_header('Content-Disposition', 'attachment', filename=('gbk', '', receiver_filename))
        msg.attach(xlsxpart)

        # 登陆且发送邮件
        server = smtplib.SMTP_SSL(smtpserver, 465)
        server.login(sender, my_pass)
        server.sendmail(sender, receiver, msg.as_string())
        server.quit()
        print("邮件发送成功")
        if del_file == True:
            if os.path.exists(filepath):
                os.remove(filepath)
                print("文件已删除")
            else:
                print("没有文件可以供删除")

    except Exception as e:
        print(e)
    return "ok"

发送不带附件的html格式的邮件

def send_no_path(email_title, content, receiver, smtpserver, nick_name,
                 sender, my_pass):
    """
    @auth 
    发送不带附件的html格式的邮件
    """
    # 创建一个不带附件的实例
    msg = MIMEText(content, "html", 'utf-8')
    # 邮件标题
    msg['Subject'] = email_title
    # 发送人/收件人/抄送人
    msg['From'] = formataddr([nick_name, sender])
    msg['To'] = ','.join(receiver)
    smtpobj = smtplib.SMTP_SSL(smtpserver, 465)
    try:
        # 连接到服务器
        smtpobj.connect(smtpserver, 465)
        # 登陆
        smtpobj.login(sender, my_pass)
        # 发送
        smtpobj.sendmail(sender, receiver, msg.as_string())
    except Exception:
        print('ERROR:邮件发送错误')
    finally:
        smtpobj.quit()

接收邮件内容

class MailFileDownload:
    """
    @author: 
    @date:2021/11/17

    通过主题或者发件人为标签自动获取最新一封邮件的正文和附件

    Attributes:
        target_subject:要获取的邮件主题
        target_from:要获取的邮件的发件人
        file_download_path:附件下载路径
        server:邮箱服务器
        user:邮箱登陆账号
        password:邮箱登陆密码

    实用方法:
        mail_text:获取邮件正文,返回字符串形式的正文
        mail_file:下载邮件附件到指定路径,返回None
        mail_file_text:获取邮件附件和正文,返回正文
    """
    logging.basicConfig(level=logging.INFO, format="$asctime - $levelname - $message", style='$')

    def __init__(self, target_subject=None, target_from=None, file_download_path=None, server,
                 user, password):
        self.logger = logging.getLogger('email')
        self.target_subject = target_subject
        self.target_from = target_from
        self.p = POP3(server)
        self.logger.info(self.p.getwelcome().decode('utf-8'))
        self.p.user(user)
        self.p.pass_(password)
        self.num = len(self.p.list()[1])  # 获取邮件位置的列表
        self.logger.info(f'共有{self.num}份邮件')
        if file_download_path[-1] == '/':
            self.file_download_path = file_download_path
        else:
            self.file_download_path = file_download_path + '/'
        # self.mail = Parser().parsestr(b'\r\n'.join(text_).decode('utf-8', 'ignore'))

    def __target_mail(self):
        """获取指定的邮件信息"""
        for i in range(self.num, 0, -1):
            # 获取邮件信息,返回元组,第二个值为邮件信息
            text_ = self.p.retr(i)[1]
            # 导入为mail格式
            mail = Parser().parsestr(b'\r\n'.join(text_).decode('utf-8', 'ignore'))
            # 比较主题是否是目标主题
            subject = mail.get('Subject')
            if subject:
                # 返回元组,索引0为正文内容,索引1为编码
                dh = decode_header(subject)
                result = dh[0][0].decode(dh[0][1])
            from_ = mail.get('From')
            if from_:
                addr = parseaddr(from_)[1]
            if self.target_from == addr or self.target_subject == result:
                break
        else:
            self.logger.warning('未找到指定主题或发件人的邮件,请检查参数')
            exit()
        return result, addr, mail

    @staticmethod
    def guess_charset(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

    def __mail_text(self, mail):
        for part in mail.walk():
            charset = self.guess_charset(part)
            content_type = part.get_content_type()
            if content_type == 'text/plain':
                content = part.get_payload(decode=True).decode(charset)
                break
        else:
            self.logger.warning('该邮件缺失正文或正文格式不是txt,请检查邮件')
            content = None
        return content

    def __mail_file(self, mail):
        """下载邮件附件"""
        for part in mail.walk():
            # 获取附件名称
            filename = part.get_filename()
            if filename:
                # 附件名称是乱码,用decode_header解码一下
                filename = decode_header(filename)
                filename = filename[0][0].decode(filename[0][1])
                data = part.get_payload(decode=True)  # 取出文件内容
                with open(os.path.join(self.file_download_path, filename), 'wb') as fp:
                    fp.write(data)
                self.logger.info(f'{filename}下载完成')

    def mail_text(self):
        """
        获取邮件正文,目前只支持txt格式的,html格式的暂不支持

        :return: content
        :rtype:
        """
        try:
            result_, addr_, mail_ = self.__target_mail()  # 获取邮件标题、发件人、邮箱对象
            content = self.__mail_text(mail_)
            return content
        except Exception:
            traceback.print_exc()
        finally:
            self.p.quit()

    def mail_file(self):
        """
        获取邮件附件

        :return:
        :rtype:
        """
        try:
            result_, addr_, mail_ = self.__target_mail()  # 获取邮件标题、发件人、邮箱对象
            self.__mail_file(mail_)
        except Exception:
            traceback.print_exc()
        finally:
            self.p.quit()

    def mail_file_text(self):
        """
        获取邮件正文和附件

        :return: content
        :rtype: str
        """
        try:
            result_, addr_, mail_ = self.__target_mail()  # 获取邮件标题、发件人、邮箱对象
            self.__mail_file(mail_)
            content = self.__mail_text(mail_)
            return content
        except Exception:
            traceback.print_exc()
        finally:
            self.p.quit()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值