AliYun-sms

AliYun-sms

一、使用详情:

第1步:访问阿里云网址,免费开通

第2步:查看新手引导

第3步:查看开发指南

二、练习

#!/usr/bin/env python
#coding=utf-8

#pip3 install aliyun-python-sdk-core
#pip geetest
#pip requests

from django.conf import settings
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
# client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-hangzhou')
client = AcsClient(settings.ACCESSKEY_ID, settings.ACCESS_KEY_SECRET, 'cn-hangzhou')

def send_sms(phone,code):
    request = CommonRequest()
    request.set_accept_format('json')
    request.set_domain('dysmsapi.aliyuncs.com')
    request.set_method('POST')
    request.set_protocol_type('https') # https | http
    request.set_version('2017-05-25')
    request.set_action_name('SendSms')

    request.add_query_param('RegionId', "cn-hangzhou")
    request.add_query_param('PhoneNumbers', phone)
    request.add_query_param('SignName', settings.SMS_TEMPLATE_CONF.get('SignName'))
    request.add_query_param('TemplateCode', settings.SMS_TEMPLATE_CONF.get('TemplateCode'))
    request.add_query_param('TemplateParam', "{'code':%s}"%(code))

    response = client.do_action(request)
    # python2:  print(response)
    print(str(response, encoding = 'utf-8'))


import random
def get_code():
    return "".join(random.sample([str(i) for i in range(0,10)],6))
utils/sms.py
# 邮箱
EMAIL_HOST = 'smtp.exmail.qq.com'  # 如果是 163 改成 smtp.163.com
EMAIL_PORT = 465
EMAIL_HOST_USER = ''  # 帐号
EMAIL_HOST_PASSWORD = ''  # 密码
# DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
EMAIL_USE_SSL = True

# 滑动验证
# pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c"
# pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4"
PC_GEETEST_ID = "13e4f7b3b8323da2b0ff9950b7ab76bc"
PC_GEETEST_KEY = "2b7352c63ed6252df1762fb29c54ee92"

# 短信
ACCESSKEY_ID = '***********'
ACCESS_KEY_SECRET = '***********'
SMS_TEMPLATE_CONF = {
    "TemplateCode": "SMS_178466533",
    "TemplateParam": "{'code':%s}",
    "SignName": "枝桠", }
settings.py
    re_path(r'^sign/$', views.sign,name='sign'),
    re_path(r'^pc-geetest/register', views.pcgetcaptcha, name='pcgetcaptcha'),
    re_path(r'^pc-geetest/ajax_validate', views.pcajax_validate, name='pcajax_validate'),
    re_path(r'^pc-geetest/get_phone_code', views.get_phone_code, name='get_phone_code'),
urls.py
from geetest import GeetestLib
from django.conf import settings
from utils import sms

def pcajax_validate(request):
    if request.method == "POST":
        gt = GeetestLib(settings.PC_GEETEST_ID, settings.PC_GEETEST_KEY)
        challenge = request.POST.get(gt.FN_CHALLENGE, '')
        validate = request.POST.get(gt.FN_VALIDATE, '')
        seccode = request.POST.get(gt.FN_SECCODE, '')
        status = request.session[gt.GT_STATUS_SESSION_KEY]
        user_id = request.session["user_id"]
        if status:
            result = gt.success_validate(challenge, validate, seccode, user_id)
        else:
            result = gt.failback_validate(challenge, validate, seccode)

        #================
        if result:
            result = {"status": "success"}

            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            user = auth.authenticate(username=user, password=pwd)
            if not user:
                result['status'] = "fail"
                result['msg'] = '用户名或者密码错误'
            else:
                auth.login(request, user)  # request.user== 当前登录对象  模板中{{ request.user.username }}

            rmb = request.POST.get("rmb")
            if rmb:
                request.session.set_expiry(60 * 60 * 24 * 30)

        else:
            result = {"status":"fail"}

        #===================
        return HttpResponse(json.dumps(result))
    return HttpResponse("error")

def pcgetcaptcha(request):
    user_id = 'test'
    gt = GeetestLib(settings.PC_GEETEST_ID, settings.PC_GEETEST_KEY)
    status = gt.pre_process(user_id)
    request.session[gt.GT_STATUS_SESSION_KEY] = status
    request.session["user_id"] = user_id
    response_str = gt.get_response_str()
    return HttpResponse(response_str)


def sign(request):
    mode=request.GET.get('mode','password')
    if request.method == "POST":
        phone = request.POST.get("phone")
        code = request.POST.get("code")
        if code != request.session.get('code'):
            result = {"code": "1","msg":'手机验证码不正确'}
            return HttpResponse(json.dumps(result))

        res = models.Customer.objects.filter(phone=phone).exists()

        if res:
            result = {"code": "0", "msg": '登陆成功','url':reverse('index')}
            return HttpResponse(json.dumps(result))
        else:
            result = {"code": "2", "msg": '手机号不存在'}
            return HttpResponse(json.dumps(result))



    return render(request,'sign/sign.html',{'mode':mode})


def get_phone_code(request):
    if request.method == "POST":
        gt = GeetestLib(settings.PC_GEETEST_ID, settings.PC_GEETEST_KEY)
        challenge = request.POST.get(gt.FN_CHALLENGE, '')
        validate = request.POST.get(gt.FN_VALIDATE, '')
        seccode = request.POST.get(gt.FN_SECCODE, '')
        status = request.session[gt.GT_STATUS_SESSION_KEY]
        user_id = request.session["user_id"]
        if status:
            result = gt.success_validate(challenge, validate, seccode, user_id)
        else:
            result = gt.failback_validate(challenge, validate, seccode)

        #================

        if result:
            result = {"status": "success"}
            #二次校验成功,发短信
            code=sms.get_code()
            phone = request.POST.get("phone")
            sms.send_sms(phone,code)
            request.session['code']=code

        else:
            result = {"status":"fail"}


        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        user = auth.authenticate(username=user, password=pwd)
        if not user:
            result['status'] = "fail"
            result['msg'] = '用户名或者密码错误'
        else:
            auth.login(request, user)  # request.user== 当前登录对象  模板中{{ request.user.username }}

        rmb = request.POST.get("rmb")
        if rmb:
            request.session.set_expiry(60 * 60 * 24 * 30)
        #===================
        return HttpResponse(json.dumps(result))
    return HttpResponse("error")
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>用户登录</title>
    <!-- animate动画库 -->
    <link rel="stylesheet" href="/static/sign/animate.css">
    <!-- 全局样式 -->
    <link rel="stylesheet" href="/static/sign/global.css">
    <!-- html样式 -->
    <link rel="stylesheet" href="/static/sign/signin.css">

    <link href="/static/sign/style_https.css" rel="stylesheet">
</head>
<body>
<div class="main">
    <header>
        <section class="head-nav">
            <div class="nav-content">
                <div class="nav-logo">
                    <p class="logo">
                        <a href="/" class="logo-img1">
                            <img src="/static/sign/logo.png" alt="">
                        </a>
                        <a href="/" class="logo-img2">
                            <img src="/static/sign/logo.png" alt="">
                        </a>
                    </p>
                    <span class="pipe"></span>
                    <div class="region-toggle">登录学员系统</div>
                </div>
                <div class="nav-num">
                    <img src="/static/sign/singin-img1.jpg" alt="">
                    <div>
                        <h2>400-609-2893</h2>
                        <p>周一至周日 09:00 - 18:00</p>
                    </div>
                </div>
            </div>
        </section>
    </header>
    <div class="clearfix">
        <div class="card">
            <div class="server">
                <img src="/static/sign/logo.png" alt="" class="logo-img">
                <ul>
                    <li>
                        <img src="/static/sign/singin-img2.jpg" alt="">
                        <article>
                            <h4>免费</h4>
                            <p>全站课程免费学</p>
                        </article>
                    </li>
                    <li>
                        <img src="/static/sign/singin-img3.jpg" alt="">
                        <article>
                            <h4>前沿</h4>
                            <p>热门技术全覆盖 </p>
                        </article>
                    </li>
                    <li>
                        <img src="/static/sign/singin-img4.jpg" alt="">
                        <article>
                            <h4>口碑</h4>
                            <p>万千学子强烈推荐 </p>
                        </article>
                    </li>
                </ul>
            </div>
            <div class="login-wrap">
                <p class="tab-title">
                    {% csrf_token %}
                    <a href="{% url 'sign' %}"><span class=" {% if mode == 'password' %} this {% endif %} ">密码登录</span></a>
                    <a href="{% url 'sign' %}?mode=sms"><span
                            class=" {% if mode == 'sms' %} this {% endif %} ">短信登录</span></a>


                </p>
                <div class="auxiliary">
                    <p class="error-wrap">
                        <img src="/static/sign/singin-icon8.jpg" alt="">
                        <span class="error-text">请输入正确的手机号并获取验证码</span>
                    </p>


                    {% if mode == 'password' %}
                        <div class="passwrod-login">
                            <div class="name i-box">
                                <img src="/static/sign/singin-icon1.jpg" alt="" class="icon1">
                                <img src="/static/sign/singin-icon1-1.jpg" alt="" class="icon2">
                                <input type="text" id="user" placeholder="请输入用户名" required="">
                            </div>
                            <div class="pwd i-box">
                                <img src="/static/sign/singin-icon3.jpg" alt="" class="icon1">
                                <img src="/static/sign/singin-icon2-1.jpg" alt="" class="icon2">
                                <input type="password" id="password" placeholder="请输入账户密码" required="">
                                <div class="toggle">
                                    <img src="/static/sign/singin-icon4.png" alt="" class="icon3">
                                    <img src="/static/sign/singin-icon4-1.jpg" alt="" class="icon4">
                                </div>
                            </div>
                            <a href="#" class="forget">忘记密码?</a>
                            <div class="sliding">
                                <div id="embed-captcha"></div>
                            </div>
                            <span class="login p-login">立即登录</span>
                        </div>
                    {% else %}
                        <div class="sms-login">
                            <div class="phone i-box">
                                <img src="/static/sign/singin-icon2.jpg" alt="" class="icon1">
                                <img src="/static/sign/singin-icon3-1.jpg" alt="" class="icon2">
                                <input type="text" id="phone" placeholder="请输入手机号">
                            </div>



                            <div class="validate i-box">
                                <img src="/static/sign/singin-icon5.jpg" alt="" class="icon1">
                                <img src="/static/sign/singin-icon5-1.jpg" alt="" class="icon2">
                                <input type="text" id="code" placeholder="请输入验证码">
                                <button class="getcode">获取验证码</button>
                                <button class="countdown" id="countdown"><span>60</span>后重新发送...</button>
                            </div>
                            <div class="sliding">


                                <div id="embed-captcha"></div>

                            </div>
                            <span class="login s-login">立即登录</span>
                        </div>
                    {% endif %}



                    <p class="bottom">
                        <span href="" class="wx"><img src="/static/sign/singin-icon6.jpg" alt="">微信登录</span>
                        <a href="https://new.oldboyedu.com/signup.html" class="signup">还没有学员账号?<span>立即注册</span></a>
                    </p>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 为使用方便,直接使用jquery.js库,如您代码中不需要,可以去掉 -->
<script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>

<!-- 动效 -->
{#<script src="/static/sign/signin.js"></script>#}
<!-- 滑动验证码 -->
<script src="/static/sign/gt.js"></script>

<!-- 引入封装了failback的接口--initGeetest -->
{#<script src="http://static.geetest.com/static/tools/gt.js"></script>#}

<script>
    // 手机验证
    var outercaptchaObj = null;
    var handlerPopup = function (captchaObj) {
        // 成功的回调
        outercaptchaObj = captchaObj;
        captchaObj.onSuccess(function () {
            var validate = captchaObj.getValidate();

            //验证通过后先隐藏提示
            $('.error-wrap').hide();
            $('.sms-login .validate').removeClass('error-box');


            $(".p-login").click(function () {
                $.ajax({
                    url: "/pc-geetest/ajax_validate", // 进行二次验证
                    type: "post",
                    dataType: "json",
                    data: {
                        user: $('#user').val(),
                        pwd: $('#password').val(),
                        csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                        geetest_challenge: validate.geetest_challenge,
                        geetest_validate: validate.geetest_validate,
                        geetest_seccode: validate.geetest_seccode
                    },
                    success: function (data) {
                        if (data && (data.status === "success")) {
                            location.href = "/"
                        } else {
                            console.log(data.msg);
                            $("#error_msg").text(data.msg).css({"color": "red", "margin-left": "10px"});
                            setTimeout(function () {
                                $("#error_msg").text("");
                            }, 4000)

                        }
                    }
                });
            });

        });

        // 将验证码加到id为captcha的元素里
        captchaObj.appendTo("#embed-captcha");

        // 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html
    };

    // 验证开始需要向网站主后台获取id,challenge,success(是否启用failback)
    $.ajax({
        url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加随机数防止缓存
        type: "get",
        dataType: "json",
        success: function (data) {
            // 使用initGeetest接口
            // 参数1:配置参数
            // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
            initGeetest({
                gt: data.gt,
                challenge: data.challenge,
                product: "popup", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
                offline: !data.success, // 表示用户后台检测极验服务器是否宕机,一般不需要关注
                // 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config
            }, handlerPopup);
        }
    });

    //免密
    $('.toggle').click(function () {
        $('.error-wrap').hide();
        if ($('.pwd input').attr('type') == 'password') {
            $('.pwd input').attr('type', 'text');
            $('.icon3').show();
            $('.icon4').hide();
        } else {
            $('.pwd input').attr('type', 'password');
            $('.icon4').show();
            $('.icon3').hide();
        }
    });


    //获取验证码倒计时
    var num = 60;
    $('.getcode').click(function (e) {

        //验证手机号格式是否正确
        flag = /^1[3-9][0-9]{9}$/.test($('#phone').val());

        if (!flag) {
            $('.error-wrap').show();
            $('.sms-login .phone').addClass('error-box');
            return
        }

        var validate = outercaptchaObj.getValidate();
        if (!validate) {
            $('.error-wrap').show();
            $('.error-wrap span').text('请先通过滑动验证');
            $('.sms-login .validate').addClass('error-box');
            return
        }


        $.ajax({
            url: "/pc-geetest/get_phone_code", // 获取验证码
            type: "post",
            dataType: "json",
            data: {
                phone: $('#phone').val(),
                csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                geetest_challenge: validate.geetest_challenge,
                geetest_validate: validate.geetest_validate,
                geetest_seccode: validate.geetest_seccode
            },
            success: function (data) {
                if (data && (data.status === "success")) {

                } else {


                }
            }
        });

        var _this = $(this);
        $('.countdown').find('span').text(num);
        var timer = setInterval(function () {
            if (num > 0) {
                $('.countdown').find('span').text(num--);
                _this.hide();
                $('.countdown').show();
            } else {
                clearInterval(timer);
                num = 60;
                _this.show();
                $('.countdown').hide();
            }
        }, 1000)

    });

    //input获取焦点
    $('input').focus(function () {
        $('.error-wrap').hide();
        $('.login-wrap .i-box').removeClass('error-box');
    });


    //登录btn
    /*
    $('.p-login').click(function () {
        $('.error-wrap').show();
        $('.passwrod-login .name').addClass('error-box');
        $('.passwrod-login .pwd').addClass('error-box');
    });
    $('.s-login').click(function () {
        $('.error-wrap').show();
        $('.sms-login .phone').addClass('error-box');
        $('.sms-login .validate').addClass('error-box');
    });

    */
    $('.s-login').click(function () {
        $.ajax({
            url: "", // 获取验证码
            type: "post",
            dataType: "json",
            data: {
                phone: $('#phone').val(),
                code: $('#code').val(),
                csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
            },
            success: function (data) {
                if (data && (data.code === 0)) {
                    location.href = data.url
                } else {
                    console.log(data.msg);
                    $("#error_msg").text(data.msg).css({"color": "red", "margin-left": "10px"});
                    setTimeout(function () {
                        $("#error_msg").text("");
                    }, 4000)

                }
            }
        });

    })


</script>


</body>
</html>
sign.html

三、发送邮件

import time
from selenium import webdriver



def worker():
    driver.get(url)
    # driver.find_element_by_id('switchAccountLogin').click()
    iframe = driver.find_elements_by_tag_name('iframe')
    driver.switch_to.frame(iframe[0])

    driver.find_element_by_class_name('dlemail').send_keys(user)
    driver.find_element_by_class_name('dlpwd').send_keys(pwd)

    driver.find_element_by_id('dologin').click()
    time.sleep(10)
    driver.find_element_by_id('_mail_component_132_132').click()

    driver.find_element_by_class_name('nui-editableAddr-ipt').send_keys(to)
    driver.find_elements_by_class_name('nui-ipt-input')[2].send_keys(theme)
    driver.find_element_by_class_name('nui-close').click()
    content_iframe = driver.find_element_by_class_name('APP-editor-iframe')
    driver.switch_to.frame(content_iframe)
    driver.find_element_by_class_name('nui-scroll').send_keys(content)
    driver.switch_to.default_content()
    driver.find_element_by_class_name('nui-mainBtn-hasIcon').click()

if __name__ == '__main__':

    url = 'https://mail.163.com/'
    theme = '测试邮件'
    to = '343096080@qq.com'
    content = '测试邮件内容.................................'
    user = "yesido@163.com"  # 填写你的163账号
    pwd = '123123'  # 填写你的163密码
    driver = webdriver.Chrome(executable_path='./chromedriver.exe')
    driver.implicitly_wait(10)
    try:
        worker()
    except Exception as e:
        print(e)
    finally:
        time.sleep(3)
        driver.quit()
Selenium之发送163邮件
#########
# EMAIL #
#########

# EMAIL_HOST = "smtp.exmail.qq.com"
# EMAIL_PORT = 465
EMAIL_HOST = "smtp.163.com"
EMAIL_PORT = 25
EMAIL_HOST_USER = "yesido20060505@163.com"
# xvazehafbcbjbifd  ysvnktnxiocrcaih
# EMAIL_HOST_PASSWORD = "cqnqiizhfioubjfd"
EMAIL_HOST_PASSWORD = "JIRODMMFZZCHBFNA"   #不是邮箱的密码,是授权密码[授权码是用于登录第三方邮件客户端的专用密码。]
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
# EMAIL_USE_SSL = True
EMAIL_SUBJECT_PREFIX = "[LuffyCity] "
# 默认邮件接收方(开发人员,如果代码出现极端异常可进行邮件通知.)
DEFAULT_TO_EMAILS = [
    "343096080@qq.com",
]
settings.py
def send_email(request,*args,**kwargs):
    """
    发送邮件
    前提:请在配置文件中配置邮箱属性
    """
    from django.core.mail import EmailMultiAlternatives
    msg = EmailMultiAlternatives(
        "邮件标题", "邮件内容", from_email=settings.DEFAULT_FROM_EMAIL, to=["343096080@qq.com", ]
    )
    # 如果发送内容为`html`格式的话, 设置这个属性即可
    # msg.content_subtype = "html"
    msg.send()

    return HttpResponse("Ok")
views.py
def comment(request):
    """
    提交评论视图函数
    功能:
    1 保存评论
    2 创建事务
    3 发送邮件
    :param request:
    :return:
    """
    print(request.POST)
 
    article_id = request.POST.get("article_id")
    pid = request.POST.get("pid")
    content = request.POST.get("content")
    user_id = request.user.pk
 
    article_obj = models.Article.objects.filter(pk=article_id).first()
 
    # 事务操作
    with transaction.atomic():
        comment_obj = models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content,
                                                    parent_comment_id=pid)
        models.Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1)
 
    response = {}
 
    response["create_time"] = comment_obj.create_time.strftime("%Y-%m-%d %X")
    response["username"] = request.user.username
    response["content"] = content
 
    # 发送邮件
    from django.core.mail import send_mail
    from django.conf import settings
 
    # send_mail(
    #     "您的文章%s新增了一条评论内容"%article_obj.title,
    #     content,
    #     settings.EMAIL_HOST_USER,
    #     ["916852314@qq.com"]
    # )
 
    import threading
    t = threading.Thread(target=send_mail, args=("您的文章%s新增了一条评论内容" % article_obj.title,
                                                 content,
                                                 settings.EMAIL_HOST_USER,
                                                 ["916852314@qq.com"])
                         )
    t.start()
 
    return JsonResponse(response)
其他

Python发送邮件

一 使用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发送邮件

在setting中配置

# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com
EMAIL_PORT = 465
EMAIL_HOST_USER = '306334678@qq.com'  # 帐号
EMAIL_HOST_PASSWORD = '***'  # 密码
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
#这样收到的邮件,收件人处就会这样显示
#DEFAULT_FROM_EMAIL = 'lqz<'306334678@qq.com>'
EMAIL_USE_SSL = True   #使用ssl
#EMAIL_USE_TLS = False # 使用tls

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

view视图函数

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

    t = threading.Thread(target=send_mail, args=("您的文章%s新增了一条评论内容" ,
                                                 'ddd',
                                                 settings.EMAIL_HOST_USER,
                                                 ["616564099@qq.com"])
                         )
    t.start()

一次性发多封邮件

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。
'''

携带附件或发送html(需要接收方支持)

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

备注:send_mail 每次发邮件都会建立一个连接,发多封邮件时建立多个连接。而 send_mass_mail 是建立单个连接发送多封邮件,所以一次性发送多封邮件时 send_mass_mail 要优于 send_mail。

各大邮箱smtp服务器及端口

新浪邮箱smtp服务器
外发服务器:smtp.vip.sina.com
收件服务器:pop3.vip.sina.com
新浪免费邮件
外发服务器:smtp.sina.com.cn
收件服务器:pop3.sina.com.cn
163邮箱smtp服务器
pop: pop.163.com
smtp: smtp.163.com
QQ邮箱smtp服务器及端口
接收邮件服务器:imap.exmail.qq.com,使用SSL,端口号993
发送邮件服务器:smtp.exmail.qq.com,使用SSL,端口号465或587
yahoo邮箱smtp服务器
接:pop.mail.yahoo.com.cn
发:smtp.mail.yahoo.com
126邮箱smtp服务器
pop: pop.126.com
smtp: smtp.126.com
新浪免费邮箱
POP3:pop.sina.com
SMTP:smtp.sina.com
SMTP端口号:25
新浪VIP邮箱
POP3:pop3.vip.sina.com
SMTP:smtp.vip.sina.com
SMTP端口号:25
新浪企业邮箱
POP3:pop.sina.com
SMTP:smtp.sina.com
SMTP端口号:25
雅虎邮箱
POP3:pop.mail.yahoo.cn
SMTP:smtp.mail.yahoo.cn
SMTP端口号:25
搜狐邮箱
POP3:pop3.sohu.com
SMTP:smtp.sohu.com
SMTP端口号:25
TOM邮箱
POP3:pop.tom.com
SMTP:smtp.tom.com
SMTP端口号:25
Gmail邮箱
POP3:pop.gmail.com
SMTP:smtp.gmail.com
SMTP端口号:587 或 25
QQ邮箱
POP3:pop.exmail.qq.com
SMTP:smtp.exmail.qq.com
SMTP端口号:25
263邮箱
域名:263.net
POP3:263.net
SMTP:smtp.263.net
SMTP端口号:25
域名:x263.net
POP3:pop.x263.net
SMTP:smtp.x263.net
SMTP端口号:25
域名:263.net.cn
POP3:263.net.cn
SMTP:263.net.cn
SMTP端口号:25
域名:炫我型
POP3:pop.263xmail.com
SMTP:smtp.263xmail.com
SMTP端口号:25
21CN 免费邮箱
POP3:pop.21cn.com
SMTP:smtp.21cn.com
IMAP:imap.21cn.com
SMTP端口号:25
21CN 经济邮邮箱
POP3:pop.21cn.com
SMTP:smtp.21cn.com
SMTP端口号:25
21CN 商务邮邮箱
POP3:pop.21cn.net
SMTP:smtp.21cn.net
SMTP端口号:25
21CN 快感邮箱
POP3:vip.21cn.com
SMTP:vip.21cn.com
SMTP端口号:25
21CN Y邮箱
POP3:pop.y.vip.21cn.com
SMTP:smtp.y.vip.21cn.com
SMTP端口号:25
中华网任我邮邮箱
POP3:rwpop.china.com
SMTP:rwsmtp.china.com
SMTP端口号:25
中华网时尚、商务邮箱
POP3:pop.china.com
SMTP:smtp.china.com
SMTP端口号:25
View Code

qq邮箱配置smtp

登录qq邮箱:

 

开启smtp服务,生成授权码

 

posted @ 2019-12-11 22:52  silencio。  阅读(257)  评论(0编辑  收藏  举报