5Automate the Boring Stuff with Python(第2版)

电子邮件与短信

通信自动化

smtplibimaplibTwilio邮件模板

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第5章:电子邮件与短信

一、导读

1.1 本章学习目标

第5章讲解如何用 Python 发送电子邮件和短信:smtplib、imaplib、Twilio。

本章核心学习目标:

  • 掌握 smtplib:发送邮件
  • 理解 imaplib:接收和读取邮件
  • 了解 Twilio:发送短信

1.2 为什么本章如此重要

自动化邮件和短信通知是常见的办公自动化需求。

1.3 核心问题引导

SMTP 和 IMAP 有什么区别?

如何发送带附件的邮件?

如何安全地存储邮件密码?


二、核心概念详解

2.1 发送邮件

python
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

def send_email(to_addr, subject, body, attachment_path=None):
    smtp_server = 'smtp.gmail.com'
    smtp_port = 587
    sender = 'your_email@gmail.com'
    password = 'your_app_password'  # 使用应用专用密码
    
    msg = MIMEMultipart()
    msg['From'] = sender
    msg['To'] = to_addr
    msg['Subject'] = subject
    msg.attach(MIMEText(body, 'plain'))
    
    if attachment_path:
        with open(attachment_path, 'rb') as f:
            part = MIMEBase('application', 'octet-stream')
            part.set_payload(f.read())
            encoders.encode_base64(part)
            part.add_header('Content-Disposition', 
                          f'attachment; filename="{attachment_path.split("/")[-1]}"')
            msg.attach(part)
    
    with smtplib.SMTP(smtp_server, smtp_port) as server:
        server.starttls()
        server.login(sender, password)
        server.send_message(msg)
    
    print(f"Email sent to {to_addr}")

send_email('recipient@example.com', 'Report', 'Please find attached.', 'report.xlsx')

2.2 读取邮件

python
import imaplib
import email
from email.header import decode_header

def check_inbox():
    imap_server = 'imap.gmail.com'
    email_addr = 'your_email@gmail.com'
    password = 'your_app_password'
    
    with imaplib.IMAP4_SSL(imap_server) as mail:
        mail.login(email_addr, password)
        mail.select('inbox')
        
        _, messages = mail.search(None, 'UNSEEN')
        
        for num in messages[0].split():
            _, data = mail.fetch(num, '(RFC822)')
            raw_email = data[0][1]
            msg = email.message_from_bytes(raw_email)
            
            subject = str(decode_header(msg['Subject'])[0][0])
            print(f"Subject: {subject}")
            print(f"From: {msg['From']}")
            print(f"Date: {msg['Date']}")
            print("---")

三、实战案例

3.1 案例一:定时发送日报邮件

python
import smtplib
from email.mime.text import MIMEText
from datetime import datetime

def send_daily_report():
    today = datetime.now().strftime('%Y-%m-%d')
    
    # 收集今日数据
    report_body = f"""
    Daily Report - {today}
    
    Tasks Completed: 5
    Tasks In Progress: 3
    Blockers: None
    
    Best regards,
    Auto Reporter
    """
    
    msg = MIMEText(report_body)
    msg['Subject'] = f'Daily Report - {today}'
    msg['From'] = 'reporter@company.com'
    msg['To'] = 'team@company.com'
    
    with smtplib.SMTP('smtp.company.com', 587) as server:
        server.starttls()
        server.login('reporter@company.com', 'password')
        server.send_message(msg)

# 可以用 cron 或 schedule 库定时执行

四、本章小结

smtplib 发送邮件,imaplib 接收邮件

MIME 支持富文本和附件

使用应用专用密码而非账户密码


五、思考与练习

如何发送 HTML 格式的邮件?

如何实现邮件的自动分类和转发?


5/7电子邮件
0%