python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python收发邮件

Python实现一键收发邮件

作者:乐茵安全

这篇文章主要为大家详细介绍了如何使用Python实现一键收发邮件功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

基于 stmp 发送邮件-源码

import smtplib
from email.mime.text import MIMEText
from email.header import Header
 
# 邮件内容
subject = 'python 邮件测试'
body = '''
<div style='font-size:50px;color:blue;'>这是一个邮件正文</div>
'''
 
# 构建邮件
msg = MIMEText(body, 'html', 'utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = '自己邮箱@qq.com'
msg['To'] = '对方邮箱@qq.com'
 
# 发送邮件
smtp_server = 'smtp.qq.com'
smtp_port = 587
sender_email = '自己邮箱@qq.com'
password = '专属key'  # 在QQ邮箱设置里拿到的码
 
try:
    with smtplib.SMTP(smtp_server, smtp_port) as server:
        server.starttls()
        server.login(sender_email, password)
        server.sendmail(sender_email, [msg['To']], msg.as_string())
    print('邮件发送成功')
except smtplib.SMTPException as e:
    print('邮件发送失败:', str(e))
 

基于 stmp 发送邮件-源码分析

这段代码的主要功能是使用 Python 的smtplib库和email库来发送一封 HTML 格式的电子邮件。下面是对代码的详细分析:

导入库

import smtplib
from email.mime.text import MIMEText
from email.header import Header

smtplib:用于发送邮件。

email.mime.text.MIMEText:用于创建 MIME 格式的邮件正文。

email.header.Header:用于创建邮件的头部信息。

邮件内容和格式设置

subject = 'python 邮件测试'
body = '''
<div style='font-size:50px;color:blue;'>这是一个邮件正文</div>
'''

subject:邮件的主题。

body:邮件的正文内容,这里使用了 HTML 格式。

构建邮件

msg = MIMEText(body, 'html', 'utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = '自己邮箱@qq.com'
msg['To'] = '对方邮箱@qq.com'

使用MIMEText创建邮件正文,指定内容类型为html和字符编码为utf-8。

设置邮件的主题、发件人和收件人。注意,Header用于处理主题的编码。

发送邮件

smtp_server = 'smtp.qq.com'
smtp_port = 587
sender_email = '自己邮箱@qq.com'
password = '专属key'  # 在QQ邮箱设置里拿到的码

设置 SMTP 服务器地址、端口、发件人邮箱和密码。这里的密码应该是 QQ 邮箱的授权码,而不是 QQ 邮箱的登录密码。

尝试发送邮件

try:
    with smtplib.SMTP(smtp_server, smtp_port) as server:
        server.starttls()  # 启动TLS加密
        server.login(sender_email, password)  # 登录SMTP服务器
        server.sendmail(sender_email, [msg['To']], msg.as_string())  # 发送邮件
    print('邮件发送成功')
except smtplib.SMTPException as e:
    print('邮件发送失败:', str(e))

使用with语句创建 SMTP 连接,确保在发送完邮件后自动关闭连接。

server.starttls():启动 TLS 加密,保证邮件传输的安全性。

server.login(sender_email, password):使用发件人的邮箱和密码登录 SMTP 服务器。

server.sendmail(sender_email, [msg['To']], msg.as_string()):发送邮件,指定发件人、收件人和邮件内容。

使用try...except语句捕获可能发生的 SMTP 异常,并打印错误信息。

注意事项

确保 QQ 邮箱已经开启了 SMTP 服务,并获取了授权码。

如果使用其他邮箱服务提供商,需要修改 SMTP 服务器地址和端口。

邮件正文中的 HTML 代码可能会被邮件客户端解析为不同的样式,具体效果取决于邮件客户端的实现。

在实际应用中,建议使用更安全的方式存储和处理密码,例如使用环境变量或加密存储。

基于 pop3 获取邮件标题-源码

import poplib
from email.parser import BytesParser
from email.header import make_header, decode_header
 
# 连接到POP3服务器
try:
    pop_server = poplib.POP3_SSL('pop.qq.com', 995)
    pop_server.user('自己邮箱@qq.com')
    pop_server.pass_('专属key')
except poplib.error_proto as e:
    print(f"Error connecting to POP3 server: {e}")
    exit(1)
 
try:
    # 获取邮箱中的邮件信息
    num_emails = len(pop_server.list()[1])
 
    # 遍历每封邮件
    for i in range(num_emails):
        # 获取邮件内容
        response, lines, octets = pop_server.retr(i + 1)
        email_content = b'\r\n'.join(lines)
 
        # 解析邮件内容
        email_parser = BytesParser()
        email = email_parser.parsebytes(email_content)
 
        # 解析邮件头部信息
        email_from = make_header(decode_header(email.get('From').strip()))
        subject = make_header(decode_header(email.get('Subject').strip())) if email.get('Subject') else None
 
        if email_from:  # 只处理存在发件人的邮件
            print("------------------")
            print("From:", email_from)
            print("Subject:", subject)
        else:
            continue  # 跳过缺失发件人的邮件
except Exception as e:
    print(f"An error occurred: {e}")
finally:
    # 确保连接关闭
    pop_server.quit()

基于 pop3 获取邮件正文-源码分析

这段代码的主要功能是连接到 POP3 服务器,获取邮箱中的所有邮件,并解析每封邮件的发件人和主题。以下是对代码的详细分析:

导入库

import poplib
from email.parser import BytesParser
from email.header import make_header, decode_header

poplib:用于连接和操作 POP3 服务器。

email.parser.BytesParser:用于解析邮件内容。

email.header.make_header 和 email.header.decode_header:用于解析和解码邮件头部信息。

连接到 POP3 服务器

try:
    pop_server = poplib.POP3_SSL('pop.qq.com', 995)
    pop_server.user('自己邮箱@qq.com')
    pop_server.pass_('专属key')
except poplib.error_proto as e:
    print(f"Error connecting to POP3 server: {e}")
    exit(1)

使用POP3_SSL连接到 POP3 服务器,指定服务器地址和端口(POP3S 默认端口为 995)。

使用user和pass_方法登录到邮箱,其中pass_是password的别名,因为password是 Python 的保留字。

如果连接或登录失败,捕获poplib.error_proto异常并打印错误信息,然后退出程序。

获取和解析邮件

try:
    # 获取邮箱中的邮件数量
    num_emails = len(pop_server.list()[1])
 
    # 遍历每封邮件
    for i in range(num_emails):
        # 获取邮件内容
        response, lines, octets = pop_server.retr(i + 1)
        email_content = b'\r\n'.join(lines)
 
        # 解析邮件内容
        email_parser = BytesParser()
        email = email_parser.parsebytes(email_content)
 
        # 解析邮件头部信息
        email_from = make_header(decode_header(email.get('From').strip()))
        subject = make_header(decode_header(email.get('Subject').strip())) if email.get('Subject') else None
 
        # 打印发件人和主题
        if email_from:
            print("------------------")
            print("From:", email_from)
            print("Subject:", subject)
        else:
            continue
except Exception as e:
    print(f"An error occurred: {e}")

使用list方法获取邮箱中的邮件列表,并计算邮件数量。

遍历每封邮件,使用retr方法获取邮件内容。

使用BytesParser解析邮件内容。

解析和解码邮件的发件人和主题,并打印出来。如果邮件缺少发件人信息,则跳过该邮件。

捕获并打印可能发生的任何异常。

关闭连接

finally:
    pop_server.quit()

使用quit方法确保在程序结束前关闭与 POP3 服务器的连接。

注意事项

安全性:在实际应用中,不建议将邮箱密码硬编码在代码中。可以使用环境变量或配置文件来存储敏感信息。

错误处理:代码已经包含了一些基本的错误处理,但在生产环境中可能需要更详细的错误处理和日志记录。

性能考虑:如果邮箱中有大量邮件,逐封下载和解析可能会很慢。可以考虑使用更高效的邮件处理方法,如分页获取邮件或使用 IMAP 协议。

邮件内容处理:当前代码只解析了邮件的发件人和主题。如果需要处理邮件正文或其他附件,需要进一步扩展代码。

基于 pop3 获取邮件内容-源码

import poplib
from email.parser import BytesParser
from email.policy import default
from email.header import make_header, decode_header
import logging
 
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
 
def get_html_payload(email_message):
    if email_message.is_multipart():
        for part in email_message.iter_parts():
            content_type = part.get_content_type()
            if content_type == 'text/html':
                return part.get_content()
    elif email_message.get_content_type() == 'text/html':
        return email_message.get_content()
 
 
# 连接到POP3服务器
try:
    pop_server = poplib.POP3_SSL('pop.qq.com', 995)
    pop_server.user('自己邮箱@qq.com')
    pop_server.pass_('专属key')  # 确保密码正确
    logging.info("Successfully connected to POP3 server.")
except poplib.error_proto as e:
    logging.error(f"Failed to connect to POP3 server: {e}")
    exit(1)
except Exception as e:
    logging.error(f"An unexpected error occurred while connecting to POP3 server: {e}")
    exit(1)
 
# 获取邮箱中的邮件信息
try:
    num_emails = len(pop_server.list()[1])
    logging.info(f"Found {num_emails} emails in the inbox.")
except poplib.error_proto as e:
    logging.error(f"Failed to list emails: {e}")
    pop_server.quit()
    exit(1)
except Exception as e:
    logging.error(f"An unexpected error occurred while listing emails: {e}")
    pop_server.quit()
    exit(1)
 
# 遍历每封邮件
for i in range(num_emails):
    try:
        # 获取邮件内容
        response, lines, octets = pop_server.retr(i + 1)
        email_content = b'\r\n'.join(lines)
 
        # 解析邮件内容
        email_parser = BytesParser(policy=default)
        email = email_parser.parsebytes(email_content)
 
        # 解析邮件头部信息
        email_from = email.get('From').strip()
        email_from = str(make_header(decode_header(email_from)))
        if email_from:  # 只处理存在发件人的邮件
            # 解析邮件主题
            subject = email.get('Subject').strip()
            decoded_subject = str(make_header(decode_header(subject))) if subject else None
 
            # 提取邮件正文
            email_body = get_html_payload(email)
            if email_body:
                print("------------------")
                print("From:", email_from)
                print("Subject:", decoded_subject)
                print("Body:", email_body.decode('utf-8', errors='ignore'))
            else:
                logging.warning(f"No HTML body found in email {i + 1}.")
        else:
            logging.warning(f"No sender found in email {i + 1}.")
    except poplib.error_proto as e:
        logging.error(f"Failed to process email {i + 1}: {e}")
    except UnicodeDecodeError as e:
        logging.error(f"Failed to decode email body in email {i + 1}: {e}")
    except Exception as e:
        logging.error(f"An unexpected error occurred while processing email {i + 1}: {e}")
 
# 关闭连接
pop_server.quit()

基于 pop3 获取邮件内容-源码解析

这段代码的主要功能是连接到 POP3 服务器,获取邮箱中的所有邮件,并解析每封邮件的发件人、主题和 HTML 正文。以下是对代码的详细分析:

导入库和配置日志

import poplib
from email.parser import BytesParser
from email.policy import default
from email.header import make_header, decode_header
import logging

导入所需的库。

配置日志记录,设置日志级别为 INFO,并定义日志格式。

定义函数get_html_payload

def get_html_payload(email_message):
    ...

这个函数用于从邮件消息中提取 HTML 正文。它首先检查邮件是否为多部分邮件,然后遍历每个部分,查找内容类型为text/html的部分并返回其内容。如果邮件不是多部分的,但内容类型为text/html,则直接返回其内容。

连接到 POP3 服务器

try:
    ...
except poplib.error_proto as e:
    ...
except Exception as e:
    ...

这部分代码尝试连接到 POP3 服务器,并处理可能发生的异常。如果连接成功,它会记录一条 INFO 级别的日志。如果连接失败,它会记录一条 ERROR 级别的日志并退出程序。

获取和解析邮件

try:
    ...
except poplib.error_proto as e:
    ...
except Exception as e:
    ...

这部分代码获取邮箱中的邮件列表,并遍历每封邮件进行处理。对于每封邮件,它执行以下操作:

使用retr方法获取邮件内容。

使用BytesParser解析邮件内容。

解析邮件的发件人和主题,并对它们进行解码。

使用get_html_payload函数提取 HTML 正文。

如果找到 HTML 正文,则打印发件人、主题和正文。否则,记录一条 WARNING 级别的日志。

在处理每封邮件时,代码都会捕获并处理可能发生的异常,包括poplib.error_proto(POP3 协议错误)、UnicodeDecodeError(解码错误)和其他意外错误。

关闭连接

pop_server.quit()

在处理完所有邮件后,代码使用quit方法关闭与 POP3 服务器的连接。

注意事项和改进点

安全性:密码硬编码在代码中是不安全的。建议使用环境变量或配置文件来存储敏感信息。

错误处理:代码已经包含了一些基本的错误处理,但在生产环境中可能需要更详细的错误处理和日志记录。

性能考虑:如果邮箱中有大量邮件,逐封下载和解析可能会很慢。可以考虑使用更高效的邮件处理方法,如分页获取邮件或使用 IMAP 协议。

邮件内容处理:当前代码只解析了邮件的发件人、主题和 HTML 正文。如果需要处理邮件附件或其他类型的内容,需要进一步扩展代码。

日志记录:可以考虑使用更高级的日志记录库(如loguru),以提供更丰富的日志功能和更好的性能。

基于 pop3 获取邮件完整-源码

import os
import base64
import poplib
from email import policy
from email.parser import BytesParser
from email.header import decode_header, make_header
 
 
# 定义EmailClient类,用于连接到POP3服务器并从指定的邮件地址获取邮件
class EmailClient:
    # 在初始化函数中,设置POP3服务器的来源、用户、密码和待查询的目标邮件地址
    def __init__(self, host, user, password, target_email):
        self.pop_server = poplib.POP3_SSL(host)  # 使用POP3协议通过SSL安全连接到邮件服务器
        self.pop_server.user(user)  # 输入用户邮箱
        self.pop_server.pass_(password)  # 输入用户邮箱密码
        self.target_email = target_email  # 输入待查询的目标邮件地址
 
    # 定义一个函数,用以清除文件名中的无效字符
    def sanitize_folder_name(self, name):
        invalid_characters = "<>:\"/\\|?*@"
        for char in invalid_characters:  # 遍历所有无效字符
            name = name.replace(char, "_")  # 将无效字符替换为下划线
        return name  # 返回清理后的名称
 
    # 定义一个函数,用以提取邮件的payload(有效载荷,即邮件主体内容)
    def get_payload(self, email_message):
        if email_message.is_multipart():  # 判断邮件是否为多部分邮件
            for part in email_message.iter_parts():  # 如果是,则遍历其中的每一部分
                content_type = part.get_content_type()  # 获取该部分的内容类型
                if content_type == 'text/html':  # 如果内容类型为HTML,则返回该部分内容
                    return part.get_content()
                elif content_type == 'text/plain':  # 如果内容类型为纯文本,则返回该部分内容
                    return part.get_content()
        elif email_message.get_content_type() == 'text/html':  # 如果邮件非多部分形式,且为HTML类型,则返回邮件内容
            return email_message.get_content()
        elif email_message.get_content_type() == 'text/plain':  # 如果邮件非多部分形式,且为纯文本类型,则返回邮件内容
            return email_message.get_content()
 
    # 定义一个函数,用以获取邮件信息
    def fetch_email(self):
        num_emails = len(self.pop_server.list()[1])  # 获取邮箱内的邮件数量
 
        # 遍历每一封邮件
        for i in range(num_emails):
            # 获取邮件内容
            response, lines, octets = self.pop_server.retr(i + 1)  # retr函数返回指定邮件的全部文本
            email_content = b'\r\n'.join(lines)  # 将所有行连接成一个bytes对象
 
            # 解析邮件内容
            email_parser = BytesParser(policy=policy.default)  # 创建一个邮件解析器
            email = email_parser.parsebytes(email_content)  # 解析邮件内容,返回一个邮件对象
 
            # 解析邮件头部信息并提取发件人信息
            email_from = email.get('From').strip()  # 获取发件人信息,并去除尾部的空格
            email_from = str(make_header(decode_header(email_from)))  # 解码发件人信息,并将其转换为字符串
            if email_from == self.target_email:  # 如果发件人地址与指定的目标邮件地址一致,对邮件进行处理
                # 解析邮件时间
                email_time = email.get('Date')  # 获取邮件时间
 
                # 提取邮件正文
                email_body = self.get_payload(email)  # 获取邮件正文
 
                return email_body, email_time  # 返回邮件正文和时间
 
        print("No new emails from", self.target_email)  # 如果没有从目标邮件地址收到新邮件,打印相应信息
        return None, None  # 返回None
 
 
client = EmailClient('pop.qq.com', '自己自己@qq.com', '专属key', '对方邮箱@qq.com')
body, time = client.fetch_email()
print("Time:", time)
print("Body:", body)

基于 pop3 获取邮件完整-源码解析

这段代码定义了一个EmailClient类,用于连接到 POP3 服务器并从指定的邮件地址获取邮件。以下是对代码的详细分析:

导入库

import os
import base64
import poplib
from email import policy
from email.parser import BytesParser
from email.header import decode_header, make_header

这些库用于实现邮件的接收和处理功能。poplib用于连接 POP3 服务器,email库用于解析邮件内容。

EmailClient 类

EmailClient类包含以下方法:

__init__: 构造函数,用于初始化 POP3 服务器连接、用户名、密码和目标邮件地址。

sanitize_folder_name: 清除文件名中的无效字符,但在这段代码中并未使用。

get_payload: 提取邮件的有效载荷(邮件主体内容),支持 HTML 和纯文本格式。

fetch_email: 获取邮件信息,遍历邮箱内的所有邮件,解析邮件头部信息,提取发件人、时间和正文。

代码执行流程

创建EmailClient实例,传入 POP3 服务器地址、用户名、密码和目标邮件地址。

调用fetch_email方法获取邮件正文和时间。

打印邮件时间和正文。

详细分析

连接 POP3 服务器:使用poplib.POP3_SSL方法连接到 POP3 服务器,确保数据传输的安全性。

登录邮箱:使用user和pass_方法登录到邮箱。

获取邮件列表:使用list方法获取邮箱内的邮件数量。

遍历邮件:使用retr方法获取每封邮件的全部文本,然后使用BytesParser解析邮件内容。

解析邮件头部信息:使用get方法获取发件人、时间等信息,并使用decode_header和make_header解码发件人信息。

提取邮件正文:使用get_payload方法提取邮件正文,支持 HTML 和纯文本格式。

返回结果:如果找到目标邮件,返回邮件正文和时间;否则,打印提示信息并返回 None。

注意事项

安全性:密码硬编码在代码中是不安全的,建议使用环境变量或配置文件存储敏感信息。

错误处理:代码中没有进行详细的错误处理,例如网络异常、登录失败等情况,建议添加相应的异常处理。

资源释放:在完成邮件操作后,应该调用quit方法关闭与 POP3 服务器的连接。

编码问题:在处理邮件正文时,可能会遇到编码问题,建议添加相应的编码处理逻辑。

功能扩展:可以根据需求扩展功能,例如支持附件下载、邮件过滤等。

以上就是Python实现一键收发邮件的详细内容,更多关于Python收发邮件的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文