使用 Python 发送一封邮件

1. 简介

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议, 它是一组用于传送邮件的规则,由它来控制信件的中转方式。

Python 的 smtplib 模块对 smtp 协议进行了简单的封装,提供了一种方便的途径发送电子邮件。

2. 配置发送服务器

2.1 简介

在本节的例子中,使用 QQ 邮箱的 SMTP 服务发送邮件,需要对 QQ 邮件发送进行配置。

本节的例子中,假设用户的信息如下:

  • 用户邮件地址,假设为 zhangsan@qq.com
  • 使用 SMTP 服务的密码,需要对 QQ 邮件进行配置后获取,注意:不是登录 QQ 邮箱的密码

2.2 进入设置界面

需要在 PC 端通过浏览器登录 QQ 邮箱:

  • 点击设置,进入邮箱设置
  • 在邮箱设置中,点击账户

图片描述

2.2 设置 POP3/SMTP 发送服务器

在账户设置的 TAB 页面中,选择 “开启服务:POP3/SMTP 服务”。

图片描述

2.3 通过短信开启 POP3/SMTP 服务

选择 "开启服务:POP3/SMTP 服务"后,系统提示通过发送短信开启 POP3/SMTP 服务

图片描述

2.4 获取 SMTP 服务密码

按照系统提示操作后,系统会给出使用 SMTP 服务的密码,请记住该服务密码,在后续的小节中会使用该密码。

图片描述

3. 发送文本格式的邮件

import smtplib
from email.header import Header
from email.mime.text import MIMEText
  • 导入 smtplib 用于发送邮件
  • 导入类 Header 和 MIMEText 用于构造邮件
fromAddr ='zhangsan@qq.com'
password = 'password for smtp'
toAddr ='zhangsan@qq.com'
subject = 'hello world'
content = '你好,世界'
  • fromAddr 为发送邮件地址
  • toAddr 为目的邮件地址,设置成与发送邮件地址相同,表示向自己发送一封邮件
  • password 是使用 SMTP 服务的密码,不是 QQ 邮箱的登录密码,请查看第 2 小节
  • subject 是邮件标题
  • content 是邮件内容
def makeMail():
    mail = MIMEText(content, 'plain', 'utf-8') 
    mail['From'] = Header(fromAddr, 'utf-8')
    mail['To'] = Header(toAddr, 'utf-8')
    mail['Subject'] = Header(subject, 'utf-8')
    return mail
  • 在第 1 行,函数 makeMail() 根据 fromAddr、toAddr、subject、content 构造一封邮件
  • 在第 2 行,使用 MIMEText 构造一个文本格式的邮件
    • MIMEText 的第二个参数 plain,表示邮件的内容是文本格式
  • 在第 3 行,构造邮件头 From
  • 在第 4 行,构造邮件头 To
  • 在第 5 行,构造邮件头 Subject
def sendMail(mail):
    server = smtplib.SMTP_SSL("smtp.qq.com")
    server.login(fromAddr, password)
    server.sendmail(fromAddr, toAddr, mail.as_string())  
    server.quit()
  • 在第 1 行,函数 sendMail 调用 SMTP 服务发送邮件 mail
  • 在第 2 行,获取 SMTP 服务器,使用 QQ 发送服务
  • 在第 3 行,登录 SMTP 服务
  • 在第 4 行,通过 SMTP 服务器发送服务
mail = makeMail()
sendMail(mail)
print('发送邮件成功')

运行程序,在 QQ 邮箱中收到邮件:

图片描述

4. 发送 html 格式的邮件

import smtplib
from email.header import Header
from email.mime.text import MIMEText
  • 导入 smtplib 用于发送邮件
  • 导入类 Header 和 MIMEText 用于构造邮件
fromAddr ='zhangsan@qq.com'
password = 'password for smtp'
toAddr ='zhangsan@qq.com'
subject = 'hello with html content'
content = '<b>Please click</b> <a href="https://www.imooc.com">imooc</a>'
  • fromAddr 为发送邮件地址
  • toAddr 为目的邮件地址,设置成与发送邮件地址相同,表示向自己发送一封邮件
  • password 是使用 SMTP 服务的密码,不是 QQ 邮箱的登录密码,请查看第 2 小节
  • subject 是邮件标题
  • content 是邮件内容,例子中使用 HTML 格式的文本
def makeMail():
    mail = MIMEText(content, 'html', 'utf-8') 
    mail['From'] = Header(fromAddr, 'utf-8')
    mail['To'] = Header(toAddr, 'utf-8')
    mail['Subject'] = Header(subject, 'utf-8')
    return mail
  • 在第 1 行,函数 makeMail() 根据 fromAddr、toAddr、subject、content 构造一封邮件
  • 在第 2 行,使用 MIMEText 构造一个文本格式的邮件
    • MIMEText 的第二个参数 html,表示邮件的内容是 HTML 格式
  • 在第 3 行,构造邮件头 From
  • 在第 4 行,构造邮件头 To
  • 在第 5 行,构造邮件头 Subject
def sendMail(mail):
    server = smtplib.SMTP_SSL("smtp.qq.com")
    server.login(fromAddr, password)
    server.sendmail(fromAddr, toAddr, mail.as_string())  
    server.quit()
  • 在第 1 行,函数 sendMail 调用 SMTP 服务发送邮件 mail
  • 在第 2 行,获取 SMTP 服务器,使用 QQ 发送服务
  • 在第 3 行,登录 SMTP 服务
  • 在第 4 行,通过 SMTP 服务器发送服务
mail = makeMail()
sendMail(mail)
print('发送邮件成功')

运行程序,在 QQ 邮箱中收到邮件:

图片描述

5. 发送带有附件的邮件

5.1 附件 hello.c

在当前目录下,创造文件 hello.c,内容如下:

#include <stdio.h>

int main()
{
    printf("hellon");
    return 0;
}

5.2 发送带有附件的邮件

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
  • 导入 smtplib 用于发送邮件
  • 导入类 Header 和 MIMEText 用于构造邮件
  • 导入类 MIMEMultipart 用于构造带有附件的邮件
fromAddr ='zhangsan@qq.com'
password = 'password for smtp'
toAddr ='zhangsan@qq.com'
subject = 'hello with attachment'
content = '你好,请查收附件'
  • fromAddr 为发送邮件地址
  • toAddr 为目的邮件地址,设置成与发送邮件地址相同,表示向自己发送一封邮件
  • password 是使用 SMTP 服务的密码,不是 QQ 邮箱的登录密码,请查看第 2 小节
  • subject 是邮件标题
  • content 是邮件内容
def makeAttachment(filename):
    file = open(filename, 'rb')
    blob = file.read()
    attachment = MIMEText(blob, 'base64', 'utf-8')
    attachment["Content-Type"] = 'application/octet-stream'
    attachment["Content-Disposition"] = 'attachment; filename="%s"' % filename
    return attachment
  • 在第 1 行,函数 makeAttachment 构造一个附件
  • 在第 2 行到第 3 行,读取当前目录下的文件 filename 的内容
  • 在第 3 行,构造附件对象 attachment
  • 在第 4 行到第 5 行,设置附件属性
def makeMail():
    mail = MIMEMultipart()
    mail['From'] = Header(fromAddr, 'utf-8')
    mail['To'] = Header(toAddr, 'utf-8')
    mail['Subject'] = Header(subject, 'utf-8')
    mail.attach(MIMEText(content, 'plain', 'utf-8'))
    return mail
  • 在第 1 行,函数 makeMail() 根据 fromAddr、toAddr、subject、content 构造一封邮件
  • 在第 2 行,使用 MIMEMultipart 构造一个带有附件的邮件
  • 在第 3 行,构造邮件头 From
  • 在第 4 行,构造邮件头 To
  • 在第 5 行,构造邮件头 Subject
  • 在第 6 行,设置邮件的正文 content
def sendMail(mail):
    server = smtplib.SMTP_SSL("smtp.qq.com")
    server.login(fromAddr, password)
    server.sendmail(fromAddr, toAddr, mail.as_string())  
    server.quit()
  • 在第 1 行,函数 sendMail 调用 SMTP 服务发送邮件 mail
  • 在第 2 行,获取 SMTP 服务器,使用 QQ 发送服务
  • 在第 3 行,登录 SMTP 服务
  • 在第 4 行,通过 SMTP 服务器发送服务
mail = makeMail()
attachment = makeAttachment('hello.c')
mail.attach(attachment)
sendMail(mail)
print('发送邮件成功')
  • 在第 2 行,构造一个附件 hello.c
  • 在第 3 行,将附件加入到邮件中

运行程序,在 QQ 邮箱中收到邮件:

图片描述