目录
以下都 以 QQ邮箱 为发送方举例;
使用 QQ邮箱发送邮件,需要到 “设置”=>“账号” 中 开启 POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务:


开启服务后,点击 管理服务:

然后会跳转到账号与安全页面,点击生成授权码以生成授权码,并记录下授权码:

参考:
https://wx.mail.qq.com/list/readtemplate?name=app_intro.html#/agreement/authorizationCode
- import smtplib
- import time
- from email.mime.text import MIMEText
-
- def send_QQ_email_plain():
- sender = user = 'sender@qq.com' # 发送方的邮箱账号
- passwd = 'abcdefgxxxxx' # 授权码
-
- receiver = 'receiver@qq.com' # 接收方的邮箱账号,不一定是QQ邮箱
-
- # 纯文本内容
- msg = MIMEText(f'Python 邮件发送测试 {time.time()}', 'plain', 'utf-8')
-
- # From 的内容是有要求的,前面的abc为自己定义的 nickname,如果是ASCII格式,则可以直接写
- msg['From'] = f'abc
' - msg['To'] = receiver
- msg['Subject'] = 'Python SMTP 邮件测试' # 点开详情后的标题
-
- try:
- # 建立 SMTP 、SSL 的连接,连接发送方的邮箱服务器
- smtp = smtplib.SMTP_SSL('smtp.qq.com', 465)
-
- # 登录发送方的邮箱账号
- smtp.login(user, passwd)
-
- # 发送邮件 发送方,接收方,发送的内容
- smtp.sendmail(sender, receiver, msg.as_string())
-
- print('邮件发送成功')
-
- smtp.quit()
- except Exception as e:
- print(e)
- print('发送邮件失败')
对于 msg['Form'] 的要求:

如果自定义的 nickname 是非 ASCII 字符,则直接写会报错,如:
msg['From'] = f'好 '

正确的格式为:
- msg['From'] = f'=?UTF-8?B?{base64.b64encode("好".encode()).decode()}?=
' -
如果接收方是 QQ 邮箱,则前面的 nickname 会显示在该位置:

如果不需要自己定义 nickname,也可以直接使用邮箱账号:
msg['From'] = '12345@qq.com'
则会显示邮箱账号:

点开邮件查看详情:

- import base64
- import smtplib
- import time
- from email.mime.text import MIMEText
-
- def send_QQ_mail_HTML():
- user = 'sender@qq.com'
- passwd = 'abcdefxxxx'
- receiver = 'receiver@qq.com'
-
- # 直接写
- # html_content = '''
- #
这个是邮件的内容
- # '''
-
- # 读入 html 文件的内容
- with open('./for_email.html', mode='r', encoding='utf-8') as f:
- html_content = f.read()
-
- # 指定类型是 html
- msg = MIMEText(html_content, 'html', 'utf-8')
- msg['From'] = user
- msg['To'] = receiver
- msg['Subject'] = '测试发送 HTML 内容'
-
- try:
- smtp = smtplib.SMTP_SSL('smtp.qq.com', 465)
- smtp.login(user, passwd)
- smtp.sendmail(user, receiver, msg.as_string())
- print('发送成功')
- except:
- print('发送失败')
-
for_email.html 的内容:
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Titletitle>
- <style>
- h1{
- color: brown;
- }
- p{
- margin: 5px;
- color: purple;
- }
- style>
- head>
- <body>
- <h1>这是一个邮件内容的标头h1>
- <img src="https://img1.baidu.com/it/u=1890390320,3399874998&fm=253&fmt=auto&app=120&f=JPEG?w=1422&h=800">
- <div>
- <h3>From合法性检查h3>
- <p>一、根据RFC5322协议,邮件标头中需要包含'From'信息。p>
- <p>二、根据RFC2047, RFC822协议,邮件标头中的'From'形式为:p>
- <p>1. 邮箱地址形式:prefix@domain, 如 'abc@qq.com'。p>
- <p>2. 昵称+空格+<邮箱地址>形式:nickname <prefix@domain>,其中,nickname为ASCII字符集中字符组合或编码文本:p>
- <p>(1)如果昵称全为ASCII字符,如'ABC',邮箱地址为'abc@qq.com',则标头中的'From'为'ABC <abc@qq.com>'。
- 注意'ABC'和'<abc@qq.com>'之间用空格隔开;p>
- <p>(2)如果昵称包含非ASCII字符,如中文,则请使用base64对昵称进行编码。nickname最终的形式为
- :"=?" charset "?" encoding "?" encoded-text "?="。其中,charset为字符集;
- encoding为编码方式,'B'代表base64;encoded-text为编码后的文本。例如,昵称为'QQ邮箱昵称示例',
- 邮箱地址为'abc@qq.com',则对昵称进行base64编码,字符集使用UTF-8,则
- nickname为 '=?UTF-8?B?UVHpgq7nrrHmmLXnp7DnpLrkvos=?=',最终邮件标头中的
- 'From'为'"=?utf-8?B?UVHpgq7nrrHmmLXnp7DnpLrkvos=?=" <abc@qq.com>'。
- 注意编码文本和邮件地址间用空格隔开。p>
- div>
- body>
- html>
该html中含有引用了外链的img图片,如果接收方为QQ邮箱,则默认不会显示图片:

如果是其他的邮箱,图片有可能可以显示(如企业微信的邮箱),html 的样式也可能会丢失不奏效。
- import base64
- import smtplib
- import time
- from email.mime.application import MIMEApplication
- from email.mime.text import MIMEText
- from email.mime.multipart import MIMEMultipart
-
- def send_QQ_email_mul():
- sender = user = 'sender@qq.com'
- passwd = 'abcdefghijk' # 不是密码,是生成的 授权码
- receiver = 'receiver@qq.com'
-
- content = MIMEMultipart() # 创建一个包含多个部分的内容
- content['From'] = user
- content['To'] = receiver
- content['Subject'] = 'Test Email'
-
- # 添加文本内容
- # text = MIMEText('this is a test email.', 'plain', 'utf-8')
- # content.attach(text)
-
- # 添加html内容
- with open('./for_email.html', mode='r', encoding='utf-8') as f:
- html_content = f.read()
- msg = MIMEText(html_content, 'html', 'utf-8')
- content.attach(msg)
-
- # 添加附件
- with open('./data.xlsx', 'rb') as f:
- attachment = MIMEApplication(f.read()) # 读取为附件
- attachment.add_header('Content-Disposition', 'attachment', filename='data.xlsx')
- content.attach(attachment)
-
- try:
- smtp = smtplib.SMTP_SSL('smtp.qq.com', 465)
- smtp.login(user, passwd)
- smtp.sendmail(sender, receiver, content.as_string())
- print('邮件发送成功')
- except Exception as e:
- print(e)
- print('发送邮件失败')

将 receiver 写成每个人的邮箱账号数组即可
- import base64
- import smtplib
- import time
- from email.mime.text import MIMEText
-
- def send_QQ_mail():
- sender = user = '12345@qq.com'
- passwd = 'ABCD'
-
- # 写成数组,将发给这三者
- receiver = ['abcdef@qq.com','aaa@xxx.edu.cn','abcd@gmail.com']
-
- msg = MIMEText(f'Python 邮件发送测试 {time.time()}', 'plain', 'utf-8')
- msg['From'] = f'=?UTF-8?B?{base64.b64encode("好".encode()).decode()}?=
' - msg['To'] = 'you' # 每个人都会看到这个内容
- msg['Subject'] = 'Python SMTP 邮件测试' # 点开详情后的标题
-
- try:
- # 建立 SMTP 、SSL 的连接
- smtp = smtplib.SMTP_SSL('smtp.qq.com', 465)
- # 登录
- smtp.login(user, passwd)
- # 发送邮件 发送方,接收方,发送的内容
- smtp.sendmail(sender, receiver, msg.as_string())
- print('邮件发送成功')
- smtp.quit()
- except Exception as e:
- print(e)
- print('发送邮件失败')
-