Python3 - 实现邮件的发送
阅读原文时间:2021年04月20日阅读:1

目录

一、 使用SMTP模块发送邮寄

二、 发送HTML格式右键

三、发送带附件的邮件

四、Django处理邮件的发送

4-1 settings配置

4-2 授权码的获取

4-3 视图函数

4-4 群发邮件(一次发送多份)

4-5 携带附件或发送HTML(需要接收方的支持)

4-6 基于SMTP的各大邮箱公司的 ‘服务器’ 及 ‘端口’


一、 使用SMTP模块发送邮寄

import smtplib
from email.mime.text import MIMEText
from email.header import Header
msg_from = '***@qq.com'  # 发送方邮箱
passwd = '****'  # 填入发送方邮箱的授权码(填入自己的授权码,相当于邮箱密码)
msg_to = ['****@qq.com','**@163.com','*****@163.com']  # 收件人邮箱
# msg_to = '616564099@qq.com'  # 收件人邮箱

subject = "邮件标题"  # 主题
content = "邮件内容,我是邮件内容,哈哈哈"
# 生成一个MIMEText对象(还有一些其它参数)
msg = MIMEText(content)
# 放入邮件主题
msg['Subject'] = subject
# 也可以这样传参
# msg['Subject'] = Header(subject, 'utf-8')
# 放入发件人
msg['From'] = msg_from
# 放入收件人
# msg['To'] = '616564099@qq.com'
# msg['To'] = '发给你的邮件啊'
try:
    # 通过ssl方式发送,服务器地址,端口
    s = smtplib.SMTP_SSL("smtp.qq.com", 465)
    # 登录到邮箱
    s.login(msg_from, passwd)
    # 发送邮件:发送方,收件方,要发送的消息
    s.sendmail(msg_from, msg_to, msg.as_string())
    print('成功')
except s.SMTPException as e:
    print(e)
finally:
    s.quit()

二、 发送HTML格式右键

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

msg_from = '306334678@qq.com'  # 发送方邮箱
passwd = 'ldoetnwqdjqqbjjj'  # 填入发送方邮箱的授权码(填入自己的授权码,相当于邮箱密码)
msg_to = ['616564099@qq.com']  # 收件人邮箱
# msg_to = '616564099@qq.com'  # 收件人邮箱

subject = "邮件标题"  # 主题
# *************发送html的邮件**********
content = '''
<p>Python 邮件发送测试...</p>
<p><a href="http://www.baidu.com">这是一个链接</a></p>
'''
# 生成一个MIMEText对象
msg = MIMEText(content)
# 放入邮件主题
msg['Subject'] = subject
# 也可以这样传参
# msg['Subject'] = Header(subject, 'utf-8')
# 放入发件人
msg['From'] = msg_from
# 放入收件人
# msg['To'] = '616564099@qq.com'
# msg['To'] = '发给你的邮件啊'
try:
    # 通过ssl方式发送
    s = smtplib.SMTP_SSL("smtp.qq.com", 465)
    # 登录到邮箱
    s.login(msg_from, passwd)
    # 发送邮件:发送方,收件方,要发送的消息
    s.sendmail(msg_from, msg_to, msg.as_string())
    print('成功')
except s.SMTPException as e:
    print(e)
finally:
    s.quit()

三、发送带附件的邮件

import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email import  encoders
msg_from = '306334678@qq.com'  # 发送方邮箱
passwd = '***'  # 填入发送方邮箱的授权码(填入自己的授权码,相当于邮箱密码)
msg_to = ['616564099@qq.com']  # 收件人邮箱

subject = "邮件标题"  # 主题
# 创建一个带附件的实例
msg = MIMEMultipart()
# 放入邮件主题
msg['Subject'] = subject
# 也可以这样传参
# msg['Subject'] = Header(subject, 'utf-8')
# 放入发件人
msg['From'] = msg_from

# 邮件正文内容
msg.attach(MIMEText('Python 邮件发送测试……', 'plain', 'utf-8'))

# 构造附件1,传送当前目录下的 test.txt 文件
att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="test.txt"'
msg.attach(att1)

# 构造附件2,
with open('test.png', 'rb') as f:
    # 设置附件的MIME和文件名,这里是png类型:
    mime = MIMEBase('image', 'png', filename='test.png')
    # 加上必要的头信息:
    mime.add_header('Content-Disposition', 'attachment', filename='test.png')
    mime.add_header('Content-ID', '<0>')
    mime.add_header('X-Attachment-Id', '0')
    # 把附件的内容读进来:
    mime.set_payload(f.read())
    # 用Base64编码:
    encoders.encode_base64(mime)
    # 添加到MIMEMultipart:
    msg.attach(mime)
# 构造附件3,图片格式
fp = open('test.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
# 定义图片 ID,在 HTML 文本中引用
msgImage.add_header('Content-ID', '<image1>')
msg.attach(msgImage)
try:
    # 通过ssl方式发送
    s = smtplib.SMTP_SSL("smtp.qq.com", 465)
    # 登录到邮箱
    s.login(msg_from, passwd)
    # 发送邮件:发送方,收件方,要发送的消息
    s.sendmail(msg_from, msg_to, msg.as_string())
    print('成功')
except s.SMTPException as e:
    print(e)
finally:
    s.quit()

四、Django处理邮件的发送

4-1 settings配置

# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_HOST = 'smtp.qq.com'  
# 发送邮箱公司书写格式,即网易、腾讯邮箱等;如果是 163 改成 smtp.163.com
EMAIL_PORT = 465  # 端口号
EMAIL_HOST_USER = '126333338@qq.com'  # 发送邮箱,即发送者邮箱账号
EMAIL_HOST_PASSWORD = '***'  # 授权码

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
#这样收到的邮件,收件人处就会这样显示
#DEFAULT_FROM_EMAIL = 'test<'126333378@qq.com>'

EMAIL_USE_SSL = True   #使用ssl -- qq只支持这种
#EMAIL_USE_TLS = False # 使用tls

#EMAIL_USE_SSL 和 EMAIL_USE_TLS 是互斥的,即只能有一个为 True

4-2 授权码的获取

 4-3 视图函数

from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse

from mybbs import settings
from django.core.mail import send_mail

def commit_content(request):
    '''
    评论操作
     - 评论成功后发送邮件给文章作者(注意配合settings内的设置)
     from django.core.mail import send_mail
     send_mail(subject, message, from_email, recipient_list,
              fail_silently=False, auth_user=None, auth_password=None,
              connection=None, html_message=None)
        = subject:邮件标题
        = message:邮件内容
        = from_email:邮件发送者
        = recipient_list:接收者列表,可以传多个
        - auth_user :发送邮箱公司书写格式(setting内EMAIL_HOST_USER)
        - auth_password:授权码(setting内EMAIL_HOST_PASSWORD)

        用于将单个消息发送到收件人列表的简单包装器。
        所有成员收件人列表中的收件人将在“To”字段中看到其他收件人。
        如果auth_user为空,则使用EMAIL_HOST_USER设置。
        如果auth_password为空,则使用EMAIL_HOST_PASSWORD设置。
        注意:此方法的API被冻结。要扩展的新代码功能应该直接使用EmailMessage类。

    :param request:
    :return:
    '''
    response = {'status': 100, 'msg': None}
    if request.is_ajax():
        if request.user.is_authenticated():
            user = request.user
            article_id = request.POST.get('article_id')
            content = request.POST.get('content')
            pid = request.POST.get('pid')
            # 注意字段parent_id_id,由于我的models内外键字段为parent_id,而表内的字段会自动添加_id
            with transaction.atomic():
                ret = models.Commit.objects.create(user=user, article_id=article_id, content=content, parent_id_id=pid)
                models.Article.objects.filter(pk=article_id).update(commit_num=F('commit_num') + 1)

            response['msg'] = '评论成功'
            response['content'] = ret.content
            # 把datetime类型转成字符串,因为json是无法序列化datetime
            response['time'] = ret.commit_time.strftime('%Y-%m-%d %X')
            response['user_name'] = ret.user.username
            if pid:
                # 如果是子评论,返回父评论的名字
                response['parent_name'] = ret.parent_id.user.username

            # ------------------------------------------
            # 评论成功发送邮件操作
            # 获取当前文章的文章名
            article_name = ret.article.title
            # 获取评论者
            user_name = ret.user.username
            # 使用send_mail进行
            # ret_mail = send_mail('您的%s文章被%s评论了' % (article_name, user_name), '这个人评论了:%s' % (content,),
            #                      settings.EMAIL_HOST_USER, ['616564099@qq.com'])

            # 可使用多线程进行同步操作,即等邮件发完继续执行下方代码
            from threading import Thread
            # 实例化
            t1 = Thread(target=send_mail, args=(
                '您的%s文章被%s评论了' % (article_name, user_name), '这个人评论了:%s' % (content,), settings.EMAIL_HOST_USER,
                ['616564099@qq.com']))
            t1.start()
            # ---------------------------------------------

        else:
            response['status'] = 101
            response['msg'] = '您没有登录'
    else:
        response['status'] = 101
        response['msg'] = '您请求非法'
    return JsonResponse(response)

4-4 群发邮件(一次发送多份)

from django.core.mail import send_mass_mail

message1 = ('第一封邮件标题', '这是邮件内容', 'from@example.com', ['first@example.com', 'other@example.com'])
message2 = ('第二封邮件标题', '这是邮件内容', 'from@example.com', ['second@test.com'])
'''
fail_silently: (可选)布尔值。为 False 时, send_mail 会抛出 smtplib.SMTPException 异常。
smtplib 文档列出了所有可能的异常。 这些异常都是 SMTPException 的子类
'''
send_mass_mail((message1, message2), fail_silently=False)
'''
send_mail 每次发邮件都会建立一个连接,发多封邮件时建立多个连接。
而 send_mass_mail 是建立单个连接发送多封邮件,所以一次性发送多封邮件时 send_mass_mail 要优于 send_mail。
'''

4-5 携带附件或发送HTML(需要接收方的支持)

from django.core.mail import EmailMultiAlternatives

# subject 主题 content 内容 to_addr 是一个列表,发送给哪些人
msg = EmailMultiAlternatives('邮件标题', '邮件内容', '发送方', ['接收方'])
msg.content_subtype = "html"
# 添加附件(可选)
msg.attach_file('test.txt')
# 发送
msg.send()

4-6 基于SMTP的各大邮箱公司的 ‘服务器’ 及 ‘端口’

服务商(默认服务端口:25)

pop 收件服务器 - 端口号

smtp 外发服务器 - 端口号

新浪VIP邮箱

pop3.vip.sina.com 

smtp.vip.sina.com

新浪免费邮件

pop3.sina.com.cn

smtp.sina.com.cn

新浪免费邮箱

pop.sina.com 

smtp.sina.com 

新浪企业邮箱

pop.sina.com 

smtp.sina.com 

163邮箱smtp服务器

pop.163.com

smtp.163.com

QQ邮箱smtp服务器及端口(仅SSL)

imap.exmail.qq.com - 993

smtp.exmail.qq.com - 465或587

QQ邮箱

pop.exmail.qq.com

smtp.exmail.qq.com

yahoo邮箱smtp服务器

pop.mail.yahoo.com.cn

smtp.mail.yahoo.com

雅虎邮箱

pop.mail.yahoo.cn

smtp.mail.yahoo.cn

126邮箱smtp服务器

pop.126.com

smtp.126.com

搜狐邮箱

pop3.sohu.com 

smtp.sohu.com 

TOM邮箱

pop.tom.com

smtp.tom.com

Gmail邮箱

pop.gmail.com

smtp.gmail.com - 587 或 25

263邮箱 - 域名:263.net

263.net

smtp.263.net

263邮箱 - 域名:x263.net

pop.x263.net

smtp.x263.net

263邮箱 - 域名:263.net.cn

263.net.cn

263.net.cn

263邮箱 - 域名:炫我型

pop.263xmail.com

smtp.263xmail.com

21CN 免费邮箱

pop.21cn.com

smtp.21cn.com

21CN 经济邮邮箱

pop.21cn.com

smtp.21cn.com

21CN 商务邮邮箱

pop.21cn.net

smtp.21cn.net

21CN 快感邮箱

vip.21cn.com

vip.21cn.com

21CN Y邮箱

pop.y.vip.21cn.com

smtp.y.vip.21cn.com

中华网任我邮邮箱

rwpop.china.com

rwsmtp.china.com

中华网时尚、商务邮箱

pop.china.com

smtp.china.com