邮件发送与接收

★ 代码

主程序 email_manage.py

"""
smtplib 主要用于发送邮件; poplib用于接收邮件
MIMEText: 用于表示纯文本内容的邮件部分,通常用于包含简单的文本消息,例如邮件的正文
MIMEApplication: 用于表示二进制数据,通常用于添加附件,可以将文件内容(如图像、文档等)作为附件添加到邮件中
MIMEMultipart: 用于组合多个不同类型的邮件部分,形成一个复杂的邮件结构,可以将多个 MIMEText、MIMEApplication 等对象添加到一个 MIMEMultipart 对象中,以构建包含多种内容(如文本、附件等)的邮件。
message.as_string()的作用是将包含邮件内容、头部信息等的message对象转换为符合 SMTP 协议要求的字符串格式

server.retr 返回值说明
response:这是服务器对操作请求的响应消息。它通常是一个字符串,用于指示操作是否成功,以及可能包含一些相关的状态信息。
例如,如果操作成功,响应可能是 '+OK' ;如果出现错误,响应可能包含错误描述,如 '-ERR Something went wrong' 。
lines:这是一个列表,其中包含了邮件的内容,每行作为列表的一个元素。邮件的头部信息、正文等都被按行拆分成列表中的元素。
您需要对这些行进行处理和解析,以提取出您所需的邮件信息,比如主题、发件人、收件人、正文等。
octets:这表示获取到的邮件的总字节数。
"""
import os
import time
import base64

import smtplib
import poplib
import email
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.header import Header
import email.utils
import constants


class MyEmail:

    def __init__(self, account, password):
        self.account = account
        self.password = password

    def get_smtplib_server(self):
        server = smtplib.SMTP_SSL('smtp.163.com')
        server.login(self.account, self.password)
        return server

    def get_poplib_server(self):
        server = poplib.POP3_SSL('pop.163.com', timeout=3600)
        server.user(self.account)
        server.pass_(self.password)
        return server

    def send_email(self, recv_accounts, title, content, content_format='plain', file_paths=None):
        # 添加邮件正文
        message = MIMEMultipart()
        text = MIMEText(content, content_format, 'utf-8')
        message.attach(text)

        # 添加邮件附件
        for file_path in file_paths or []:
            with open(file_path, 'rb') as rf:
                attachment = MIMEApplication(rf.read())
                attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(file_path))
            message.attach(attachment)

        # 设置接收端显示的发件人与收件人
        message['from'] = Header('MrDong <MrDong@163.com>')
        message['to'] = Header('damon__dong <damon__dong@163.com>')
        message['subject'] = title
        try:
            server = self.get_smtplib_server()
            server.sendmail('18874173262@163.com', recv_accounts, message.as_string())
        except Exception as e:
            print(f'邮件发送失败: {e}')
            return False
        else:
            print(f'邮件发送成功!')
            return True

    def get_email(self):
        try:
            server = self.get_poplib_server()
        except Exception as e:
            print(f'连接pop3服务器失败: {e}')
            return False

        # 获取邮件总数
        email_total = len(server.list()[1])

        # 根据邮件编号获取邮件信息
        response, lines, octets = server.retr(email_total)
        # 解析邮件的内容(解码并合并每行数据)
        message_content = '\n'.join([line.decode() for line in lines])
        # 将字符串形式的邮件内容转换为 email.message 实例
        message = email.message_from_string(message_content)
        # 获取邮件主题内容、编码格式、发件时间、发件人邮箱
        encode_type = email.header.decode_header(message['subject'])[0][1]
        subject_ = email.header.decode_header(message['subject'])[0][0]
        email_time_ = email.header.decode_header(message['date'])[0][0]
        email_from = email.utils.parseaddr(message['from'])[1]

        # 邮件标题解码、邮件时间转换
        subject = subject_.decode(encode_type)
        email_time = email.utils.parsedate_to_datetime(email_time_).strftime('%Y-%m-%d %H:%M:%S')
        # 获取邮件正文
        email_content = self.get_content(message)
        return {
            'subject': subject,
            'time': email_time,
            'from': email_from,
            'content': email_content
        }

    def get_content(self, mail):
        mail_object = None
        if mail.is_multipart():
            for part in mail.get_payload():
                return self.get_content(part)
        else:
            types = mail.get_content_type()
            charset = mail.get_content_charset()
            if types == 'text/plain' or types == 'text/html':
                try:
                    if charset == 'utf-8':
                        mail_object = mail.get_payload(decode=True).decode('utf-8')
                    elif charset is None:
                        mail_object = mail.get_payload(decode=True)
                    else:
                        mail_object = mail.get_payload(decode=True).decode(charset)
                except Exception as e:
                    print(f'获取邮件内容错误:{e}')
            elif types == 'text/base64':
                try:
                    mail_object = base64.b64decode(mail.get_payload()).decode(charset)
                except Exception as e:
                    print(f'邮件内容解码错误:{e}')

        return mail_object


if __name__ == '__main__':
    # 创建邮件对象
    my_email = MyEmail(constants.Netease_ACCOUNT, constants.Netease_PASSWORD)
    # 发送测试邮件
    my_email.send_email(constants.Netease_ACCOUNT, '邮件发送测试', '<h3>这里是邮件发送测试正文<h3>', content_format='html')
    time.sleep(5)
    # 读取邮件内容
    email_info = my_email.get_email()
    print(email_info)

常量文件 constants.py

# 网易邮箱授权账户
Netease_ACCOUNT = "你的163邮箱"
Netease_PASSWORD = "你的163授权密码"


posted @ 2024-07-28 00:11  CSMrDong  阅读(11)  评论(0编辑  收藏  举报