找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1422

积分

0

好友

204

主题
发表于 前天 18:46 | 查看: 5| 回复: 0

本文将介绍一个功能完善的Python批量邮件发送脚本。该脚本能够从Excel文件读取联系人列表,并使用Jinja2模板引擎生成个性化的邮件内容。脚本内置了发送间隔控制与日志记录功能,能有效规避邮件服务器的发送限制,确保大批量邮件的稳定投递。

功能概述

该邮件发送器主要包含以下核心功能:

  • 数据源:从Excel文件读取收件人姓名与邮箱地址。
  • 模板渲染:支持使用Jinja2编写HTML富文本邮件模板,也支持简单的纯文本模板。
  • 个性化:可根据每位收件人的信息动态填充邮件主题和内容。
  • 稳定发送:可配置发送间隔与每批发送数量,防止被识别为垃圾邮件或触发发送限制。
  • 完整日志:记录每次发送的成功与失败状态,便于后续核对与排查问题。

环境依赖

脚本依赖于以下三个Python库:

  • yagmail: 一个简化SMTP邮件发送过程的库。
  • pandas: 用于读取和操作Excel文件中的数据。
  • jinja2: 强大的模板引擎,用于渲染HTML邮件内容。

你可以使用pip命令进行安装:

pip install yagmail pandas jinja2

核心配置详解

1. 邮箱服务器配置 (EmailConfig)

在此配置发件邮箱的账户信息与SMTP服务器参数。请注意,部分邮箱(如163、QQ)需使用授权码而非登录密码。

class EmailConfig:
    """邮箱配置"""
    # 你的邮箱
    user: str = 'your_email@163.com'
    # 邮箱授权码(非登录密码)
    password: str = 'your_authorization_code'
    # 邮箱SMTP服务器
    host: str = 'smtp.163.com'
    # 端口(推荐使用587或465)
    port: int = '587'

2. 发件人信息与主题 (SenderInfo)

此配置类定义了发件人信息,并负责生成个性化的邮件主题。

class SenderInfo:
    """发件人信息"""
    name: str = '云栈社区'
    position: str = '技术编辑'
    company: str = '云栈科技'
    email: str = 'your_email@163.com'
    signature: str = '感谢阅读!'

    def get_subject(self, client: dict):
        """生成邮件主题,client为从Excel读取的单条客户信息"""
        return f"{self.name}致{client['name']}的问候邮件"

    def to_json(self):
        """将发件人信息转换为字典,供模板使用"""
        return {
            'name': self.name,
            'position': self.position,
            'company': self.company,
            'email': self.email,
            'signature': self.signature
        }

3. 发送行为控制 (SendSettings)

通过调整此配置,可以控制发送节奏,是避免被限流的关键。

class SendSettings:
    """发送设置"""
    # 邮件间隔(秒),避免被限制
    delay_between_emails: int = 2
    # 测试模式(开启后,所有邮件将发往自己的邮箱)
    test_mode: bool = True  # 建议先开启测试,验证无误后再设为False
    # 每批最多发送量(达到此数量后暂停60秒)
    max_emails_per_batch: int = 20

脚本核心流程解析

1. 加载客户数据

使用pandas读取Excel文件。假设Excel格式如下:

index name email
1 张三 zhangsan@example.com
2 李四 lisi@example.com
def load_clients(self) -> list[dict]:
    """加载并校验客户数据"""
    df = pd.read_excel(self.client_data_file)
    client_list = df.to_dict(orient='records')
    if not client_list:
        raise ValueError("客户数据为空")
    # 数据清洗与校验
    for client in client_list:
        if not client['email']:
            raise ValueError(f"客户 {client.get('name')} 的邮箱为空")
        if not client['name']:
            raise ValueError(f"邮箱 {client.get('email')} 的姓名为空")
        client['name'] = client['name'].strip()
        client['email'] = client['email'].strip()
    print(f"已加载 {len(client_list)} 个客户数据")
    return client_list

这是典型的Python自动化处理场景,pandas在此高效地完成了数据的读取与结构化。

2. 加载与渲染邮件模板

脚本支持两种模板:Jinja2 HTML模板和简单文本模板。

  • 文本模板 (christmas.txt):使用{client_name}{sender_company}等占位符。
    尊敬的{client_name},您好!
    我是{sender_company}的{sender_name}。
    {sender_signature}
  • Jinja2 HTML模板 (template.html):功能更强大,支持条件、循环等逻辑。
    <html><body>
        <p>尊敬的{{ client.name }},您好!</p>
        <p>我是{{ sender.company }}的{{ sender.name }}。</p>
        <p><em>{{ sender.signature }}</em></p>
    </body></html>

3. 发送邮件与日志记录

发送功能封装在send_to_client方法中,每封邮件发送无论成功失败都会记录详细的日志。

def send_to_client(self, client, content):
    """发送给单个客户"""
    try:
        subject = self.sender_info.get_subject(client=client)
        to_email = self.email_config.user if self.send_settings.test_mode else client['email']
        if self.send_settings.test_mode:
            subject = f"[测试] {subject}"

        self.yag.send(to=to_email, subject=subject, contents=content)
        # 记录成功日志
        self.sent_log.append({
            'client': client['name'],
            'email': client['email'],
            'time': datetime.now().isoformat(),
            'status': '成功'
        })
        print(f"✓已发送给 {client['name']} <{client['email']}>")
        return True
    except Exception as e:
        # 记录失败日志
        self.sent_log.append({
            'client': client['name'],
            'email': client['email'],
            'time': datetime.now().isoformat(),
            'status': f'失败: {str(e)}'
        })
        print(f"✗发送失败 {client['name']}: {e}")
        return False

4. 主运行逻辑 (run方法)

run方法串联了整个发送流程,并集成了防限流策略。

def run(self):
    """主运行函数"""
    print("开始发送个性化邮件...\n")
    client_list = self.load_clients()
    template, txt_template = self.load_template()

    for i, client in enumerate(client_list, 1):
        # 1. 生成个性化内容
        html_content, text_content = self.personalize_content(client, template, txt_template)
        # 2. 发送邮件
        self.send_to_client(client, content)
        # 3. 发送间隔延迟
        if i < len(client_list):
            time.sleep(self.send_settings.delay_between_emails)
        # 4. 分批暂停(防限流关键)
        if i % self.send_settings.max_emails_per_batch == 0:
            print(f"\n已发送 {i} 封,暂停 60 秒...")
            time.sleep(60)

    self.save_log() # 保存所有日志到CSV文件
    print(f"\n✅完成!")

如何使用脚本

  1. 准备数据:将收件人信息填入Excel文件(如clients.xlsx)。
  2. 编写模板:创建纯文本模板(如christmas.txt)或Jinja2 HTML模板。
  3. 修改配置:在config.py中正确设置邮箱授权码、发件人信息等。
  4. 测试运行:将SendSettings.test_mode设为True,运行脚本检查邮件内容与格式。
  5. 正式发送:确认无误后,将test_mode设为False,再次运行脚本开始正式批量发送。

运行入口示例:

if __name__ == "__main__":
    client_data_file = './clients/clients.xlsx'
    txt_template_file = './templates/christmas.txt'  # 或指定html模板文件
    sender = EmailSender(client_data_file=client_data_file,
                         txt_template_file=txt_template_file)
    sender.run()

总结

本脚本整合了邮件发送、数据处理与模板渲染等多个环节,通过模块化的配置和健壮的发送策略,提供了一个可用于实际生产环境的批量邮件发送解决方案。开发者可根据自身需求,轻松扩展附件支持、更复杂的模板逻辑或其他的邮件头部信息。




上一篇:FPGA作为AI机器小脑:在金融交易、边缘AI与军事装备中的核心应用
下一篇:Xubuntu 24.04 LTS安装配置与使用指南:轻量级Linux桌面系统
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 18:57 , Processed in 0.257998 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表