容联云通讯是第三方平台,能够提供短信验证码和语音通信等功能,这里只测试使用短信验证码的功能,因此只需完成注册登录(无需实名认证等)即可使用其短信验证码免费测试服务,不过免费测试服务只能给控制台中指定的三个手机号发送短信,且只能有一个短信模板可以使用.

在该网址 https://doc.yuntongxun.com/p/5a533e0c3b8496dd00dce08c 可以查看python发送短信的demo实例和源码下载.下载后目录如下:

使用时,在项目目录中新建一个文件夹(如yuntongxun)将SDK中的两个文件 CCPRestSDK.py 和 xmltojson.py 放入该文件夹中.然后再使用DEMO中的 SendTemplateSMS.py 来调用SDK中的py文件即可.这里我们不使用官方提供的 SendTemplateSMS.py ,而是将其改造封装成一个单例模式的类的方式调用,文件名为sms.py

# coding=utf-8

from .CCPRestSDK import REST

# 主帐号
accountSid = 控制台中的ACCOUNT SID # 主帐号Token
accountToken = 控制台中的AUTH TOKEN # 应用Id
appId = 控制台中的AppID
# 请求地址,格式如下,不需要写http://
serverIP = 'app.cloopen.com' # 请求端口
serverPort = '' # REST版本号
softVersion = '2013-12-26' # 发送模板短信
# @param to 手机号码
# @param datas 内容数据 格式为列表 例如:['12','34'],如不需替换请填 ''
# @param $tempId 模板Id class CCP(object):
"""自己封装的发送短信的辅助类"""
# 用来保存对象的类属性
instance = None def __new__(cls):
# 判断CCP类有没有已经创建好的对象,如果没有,创建一个对象,并且保存
# 如果有,则将保存的对象直接返回
if cls.instance is None:
obj = super(CCP, cls).__new__(cls) # 初始化REST SDK
obj.rest = REST(serverIP, serverPort, softVersion)
obj.rest.setAccount(accountSid, accountToken)
obj.rest.setAppId(appId) cls.instance = obj return cls.instance def send_template_sms(self, to, datas, temp_id):
""""""
result = self.rest.sendTemplateSMS(to, datas, temp_id)
print('result:\n', result)
# for k, v in result.iteritems():
#
# if k == 'templateSMS':
# for k, s in v.iteritems():
# print '%s:%s' % (k, s)
# else:
# print '%s:%s' % (k, v)
# smsMessageSid:ff75e0f84f05445ba08efdd0787ad7d0
# dateCreated:20171125124726
# statusCode:000000
status_code = result.get("statusCode")
if status_code == "":
# 表示发送短信成功
return 0
else:
# 发送失败
return -1 if __name__ == '__main__':
ccp = CCP()
ret = ccp.send_template_sms("", ["", ""], 1)
print(ret)

由于官方提供的代码CCPRestSDK.py是基于python2写的,本项目为python3,因此需要将其中一些python2的写法改成python3支持的语法,改写完成后为

#-*- coding: UTF-8 -*-
# Copyright (c) 2014 The CCP project authors. All Rights Reserved.
#
# Use of this source code is governed by a Beijing Speedtong Information Technology Co.,Ltd license
# that can be found in the LICENSE file in the root of the web site.
#
# http://www.yuntongxun.com
#
# An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# import md5
from hashlib import md5 # py3.x
import base64
import datetime
# import urllib2
import urllib.request as urllib2 # py3.x
import json
from .xmltojson import xmltojson
from xml.dom import minidom class REST: AccountSid=''
AccountToken=''
AppId=''
SubAccountSid=''
SubAccountToken=''
ServerIP=''
ServerPort=''
SoftVersion=''
Iflog=True #是否打印日志
Batch='' #时间戳
BodyType = 'xml'#包体格式,可填值:json 、xml # 初始化
# @param serverIP 必选参数 服务器地址
# @param serverPort 必选参数 服务器端口
# @param softVersion 必选参数 REST版本号
def __init__(self,ServerIP,ServerPort,SoftVersion): self.ServerIP = ServerIP;
self.ServerPort = ServerPort;
self.SoftVersion = SoftVersion; # 设置主帐号
# @param AccountSid 必选参数 主帐号
# @param AccountToken 必选参数 主帐号Token def setAccount(self,AccountSid,AccountToken):
self.AccountSid = AccountSid;
self.AccountToken = AccountToken;

  .......# 发送模板短信
# @param to 必选参数 短信接收彿手机号码集合,用英文逗号分开
# @param datas 可选参数 内容数据
# @param tempId 必选参数 模板Id
def sendTemplateSMS(self, to,datas,tempId): self.accAuth()
nowdate = datetime.datetime.now()
self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
#生成sig
signature = self.AccountSid + self.AccountToken + self.Batch;
signature = signature.encode('utf-8') # py3
# sig = md5.new(signature).hexdigest().upper()
sig = md5(signature).hexdigest().upper() # py3
#拼接URL
url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/SMS/TemplateSMS?sig=" + sig
#生成auth
src = self.AccountSid + ":" + self.Batch;
# auth = base64.encodestring(src).strip()
auth = base64.encodestring(src.encode()).strip()
req = urllib2.Request(url)
self.setHttpHeader(req)
req.add_header("Authorization", auth)
#创建包体
b=''
for a in datas:
b+='<data>%s</data>'%(a) body ='<?xml version="1.0" encoding="utf-8"?><SubAccount><datas>'+b+'</datas><to>%s</to><templateId>%s</templateId><appId>%s</appId>\
</SubAccount>\
'%(to, tempId,self.AppId)
if self.BodyType == 'json':
# if this model is Json ..then do next code
b='['
for a in datas:
b+='"%s",'%(a)
b+=']'
body = '''{"to": "%s", "datas": %s, "templateId": "%s", "appId": "%s"}'''%(to,b,tempId,self.AppId)
# req.add_data(body)
req.data = body.encode() # py3
data=''
try:
res = urllib2.urlopen(req);
data = res.read()
res.close()
print(data) if self.BodyType=='json':
#json格式
locations = json.loads(data)
else:
#xml格式
xtj=xmltojson()
locations=xtj.main(data)
if self.Iflog:
self.log(url,body,data)
return locations
except Exception as error:
print(error)
if self.Iflog:
self.log(url,body,data)
return {'':'网络错误'}   .......#设置包头
def setHttpHeader(self,req):
if self.BodyType == 'json':
req.add_header("Accept", "application/json")
req.add_header("Content-Type", "application/json;charset=utf-8") else:
req.add_header("Accept", "application/xml")
req.add_header("Content-Type", "application/xml;charset=utf-8")

上述语法改写可以通过运行项目,看具体报错信息一步一步改成python3的写法,直到不报错为止,但是项目虽然不报错了,可还是不能成功发送短信,返回的报错信息是 {'172001':'网络错误'},经过百度和自己验证后,发现还有三处需要注意修改:

1. 运行报错:ModuleNotFoundError: No module named 'utils'

File "/home/python/study/ihome/ihome/libs/yuntongxun/sms.py", line 3, in <module>
from .CCPRestSDK import REST
File "/home/python/study/ihome/ihome/libs/yuntongxun/CCPRestSDK.py", line 18, in <module>
from xmltojson import xmltojson
File "/home/python/.virtualenvs/flask/bin/xmltojson.py", line 23, in <module>
import utils
ModuleNotFoundError: No module named 'utils'

我一开始以为是pip3中没有安装utils,后来再看上面的几行发现找的是虚拟环境中xmltojson.py而官方SDK源码中也提供了一个xmltojson.py文件,我们应该是使用这个文件,所以在开始import xmltojson时,应该写成

from .xmltojson import xmltojson

即从当前目录的xmltojson.py中导入

2.返回的报错信息是 {'172001':'网络错误'},原因是这里访问的url是https开头的,而python升级到 2.7.9 之后引入了一个新特性,当打开一个 https 链接时,会验证一次 SSL 证书。而当目标网站使用的是自签名的证书时就会抛出此异常。解决方案如下:在 sms.py或(SendTemplateSMS.py)文件顶部插入:

import ssl

# 全局取消证书验证
ssl._create_default_https_context = ssl._create_unverified_context

3.操作完第二步之后,还是报错{'172001':'网络错误'},查看打印发现响应包体为空,说明发送数据是否有问题,后面发现给req添加请求体信息时,将原来的 py2写法:req.add_data(body),改成了py3写法:req.data = body,这时body是字符串类型,需要使用encode将其转码为byte类型,因此需要改成

req.data = body.encode()

python-在python3中使用容联云通讯发送短信验证码的更多相关文章

  1. 如何使用微信小程序云函数发送短信验证码

    其实微信小程序前端和云端都是可以调用短信平台接口发送短信的,使用云端云函数的好处是无需配置域名,也没有个数限制. 本文使用的是榛子云短信平台(http://smsow.zhenzikj.com) ,S ...

  2. 【转+修改】容联云通讯api调用短信发送调用

    转自   https://my.oschina.net/u/1995134/blog/814540 需要荣联云通讯 的 相对应SDKjar包. CCP_REST_SMS_SDK_JAVA_v2.6.3 ...

  3. Luffy之注册认证(容联云通讯短信验证)

    用户的注册认证 前端显示注册页面并调整首页头部和登陆页面的注册按钮的链接. 注册页面Register,主要是通过登录页面进行改成而成. 先构造前端页面 <template> <div ...

  4. java 阿里云接口实现发送短信验证码

    此刻自己做的小项目中,需要用到手机发送短信验证码实现注册功能,于是就去阿里云注册了账号,并实现随机发送验证码的功能 第一步:在阿里云官网登录注册   已有支付宝或淘宝的账号可以直接登录,最后需要实名认 ...

  5. 容联云通讯_提供网络通话、视频通话、视频会议、云呼叫中心、IM等融合通讯能力开放平台。

    容联云通讯_提供网络通话.视频通话.视频会议.云呼叫中心.IM等融合通讯能力开放平台. undefined

  6. Python3实现发送邮件和发送短信验证码

    Python3实现发送邮件和发送短信验证码 Python3实现发送邮件: import smtplib from email.mime.text import MIMEText from email. ...

  7. Laravel5中使用阿里大于(鱼)发送短信验证码

    在做用户注册和个人中心的安全管理时,我实现借助第三方短信平台(阿里大于(鱼))在Laravel框架中进行手机验证的设置:阿里大于,是阿里通信旗下优质便捷的云通信服务平台,整合了三大运营商的通信能力,为 ...

  8. 阿里云短信服务发送短信验证码(JAVA开发此功能)

    开发此功能需注册阿里云账号,并开通短信服务(免费开通) 充值后,不会影响业务的正常使用!(因为发送验证类短信:1-10万范围的短信是0.045元/条).开发测试使用,充2块钱测试足够了 可参考阿里云官 ...

  9. JavaWeb-SpringBoot_一个类实现腾讯云SDK发送短信

    腾讯云应用列表 传送门 使用Gradle编译项目 传送门 SDK&API:qcloudsms_java 传送门 package com.Gary.sms.controller; import ...

随机推荐

  1. 【C++和C#的区别杂谈】后自增运算符的结算时机

    C++和C#的前自增++n和后自增n++,都是先自增后取值和先取值后自增的含义,但在复杂一点的赋值语句中,我发现细节上有很大的差异. 发现这个问题主要是一个无聊的晚上,我想搞清楚后自增是什么时候结算, ...

  2. pythonic context manager知多少

    Context Managers 是我最喜欢的 python feature 之一,在恰当的时机使用 context manager 使代码更加简洁.清晰,更加安全,复用性更好,更加 pythonic ...

  3. RS232/485通信方式 保存和加载时数据的处理

    RS232/485通信方式 数据以RS232/485方式通信时,以0xA5作为开始码,以0xAE作为结束码.在开始码和结束码之间的0xA5, 0xAA, 0xAE数据需要进行转码. PC端发送数据时将 ...

  4. 队列的顺序存储与链式存储c语言实现

    一. 队列 1.队列定义:只允许在表的一端进行插入,表的另一端进行删除操作的线性表. 2.循环队列:把存储队列的顺序队列在逻辑上视为一个环. 循环队列状态: 初始时:Q.front=Q.rear=0 ...

  5. 洛谷 P4017 【最大食物链计数】

    看到这种明显的有向无环图,并且等级分明,自然而然就能想到拓补排序啦.对于这道题,我们就可以利用最短路计数的那种思想(不知道也没关系),设\(j\)是\(i\)的后继,\(dis_i\)表示以\(i\) ...

  6. Dubbo 负载均衡的实现

    前言 负载均衡是指在集群中,将多个数据请求分散在不同单元上进行执行,主要为了提高系统容错能力和加强系统对数据的处理能力. 在 Dubbo 中,一次服务的调用就是对所有实体域 Invoker 的一次筛选 ...

  7. JVM源码分析之Java对象头实现

    原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十一篇. 今天呢!灯塔君跟大家讲: JVM源码分析之Java对象头实现 HotSpot虚拟机中,对象在内存中的布局分为三 ...

  8. (三)ELK logstash input

    一,input模块 input 插件官方详解: https://www.elastic.co/guide/en/logstash/current/input-plugins.html Logstash ...

  9. python入门006

    一:可变与不可变类型 可变类型:值改变,id不变,证明改的是原值,证明原值是可以被改变的 不可变类型:值改变,id也变了,证明是产生新的值,压根没有改变原值,证明原值是不可以被修改的 2.验证 2.1 ...

  10. 执行ArrayList的remove(object)方法抛异常?

    简介 或许有很多小伙伴都尝试过如下的代码: ArrayList<Object> list = ...; for (Object object : list) { if (条件成立) { l ...