Python3 下实现 Tencent AI 调用
1、背景
a、鹅厂近期发布了自己的人工智能 api,包括身份证ocr、名片ocr、文本分析等一堆API,因为前期项目用到图形OCR,遂实现试用了一下,发现准确率还不错,放出来给大家共享一下。
b、基于python3,跟python2还是有些区别。
c、特别需要提到的就是签名生成这块,鹅厂的api说明里写的比较简单,一开始在sign的生成(https://ai.qq.com/doc/auth.shtml)上卡了好几天,后来加的官方群,咨询之后才解决。
2、签名算法
不够150字,那就正好把签名算法这块写一写。
a、官网说明如下:
按URL键值拼接字符串T
依照算法第二步要求,将参数对列表N的参数对进行URL键值拼接,值使用URL编码,URL编码算法用大写字母,例如%E8,而不是小写%e8,得到字符串T如下:
b、实际上:
参数列表是指api中所有除sign之外用到的参数都要参与计算sign。
譬如:
1)文本分析接口有4个字段,拼接串为:
app_id=10000&nonce_str=20e3408a79&text=%E8%85%BE%E8%AE%AF%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0&time_stamp=1493449657
参数名 | 参数值 |
---|---|
app_id | 10000 |
nonce_str | 20e3408a79 |
text | 腾讯开放平台 |
time_stamp | 1493449657 |
2)身份证ocr接口有6个字段,拼接串为:
app_id=&time_stamp=1511839575&nonce_str=3oxitu0qf198bh24&image=%2F9j%2F4AA************QSkZJRgA9j%2F%2F2Q%3D%3D&card_type=0&sign=2ED0122CD44DCB1FD7BC9AE1D03D64D9
参数名称 | 是否必选 | 数据类型 | 数据约束 | 示例数据 | 描述 |
---|---|---|---|---|---|
app_id | 是 | int | 正整数 | 1000001 | 应用标识(AppId) |
time_stamp | 是 | int | 正整数 | 1493468759 | 请求时间戳(秒级) |
nonce_str | 是 | string | 非空且长度上限32字节 | fa577ce340859f9fe | 随机字符串 |
sign | 是 | string | 非空且长度固定32字节 | B250148B284956EC5218D4B0503E7F8A | 签名信息,详见接口鉴权 |
image | 是 | string | 原始图片的base64编码数据(解码后大小上限1MB,支持JPG、PNG、BMP格式) | ... | 待识别图片 |
card_type | 是 | int | 整数 | 0/1 | 身份证图片类型,0-正面,1-反面 |
注意区别:不光光是参与计算的字段变化,各字段的排序也不一样。
3、实现代码
在github上上传了一下,https://github.com/jdstkxx/pyTencentAI
# -*- coding: utf-8 -*- '''
create by : joshua zou
create date : 2017.11.28
Purpose: tecent ai api
''' import requests
import base64
import hashlib
import time
import random
import os,string,glob
from PIL import Image
from io import BytesIO
from urllib.parse import urlencode
from urllib import parse
import json class MsgTencent(object):
def __init__(self,AppID=None,AppKey=None):
'''
改成你自己的API账号、密码
'''
if not AppID: AppID = ''
if not AppKey: AppKey = 'uuuuuuuuuu'
self.app_id= AppID
self.app_key= AppKey
self.img_base64str=None def get_random_str(self):
#随机生成16位字符串
rule = string.ascii_lowercase + string.digits
str = random.sample(rule, 16)
return "".join(str) def get_time_stamp(self):
return str(int(time.time())) def __get_image_base64str__(self,image):
if not isinstance(image,Image):return None
outputBuffer = BytesIO()
bg.save(outputBuffer, format='JPEG')
imgbase64 = base64.b64encode(outputBuffer.getvalue())
return imgbase64 def __get_imgfile_base64str__(self,image):
if not isinstance(image, str): return None
if not os.path.isfile(image): return None with open(image,'rb') as fp:
imgbase64 = base64.b64encode(fp.read())
return imgbase64 def get_img_base64str(self,image):
if isinstance(image, str):
self.img_base64str= self.__get_imgfile_base64str__(image)
elif isinstance(image,Image):
self.img_base64str= self.__get_imgfile_base64str__(image)
return self.img_base64str.decode() # 组装字典,MD5加密方法
'''
======================================
tencent获得参数对列表N(字典升级排序)
======================================
1\依照算法第一步要求,对参数对进行排序,得到参数对列表N如下。
参数名 参数值
app_id 10000
nonce_str 20e3408a79
text 腾讯开放平台
time_stamp 1493449657 2\按URL键值拼接字符串T
依照算法第二步要求,将参数对列表N的参数对进行URL键值拼接,值使用URL编码,URL编码算法用大写字母,例如%E8,而不是小写%e8,得到字符串T如下:
app_id=10000&nonce_str=20e3408a79&text=%E8%85%BE%E8%AE%AF%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0&time_stamp=1493449657 3\拼接应用密钥,得到字符串S
依照算法第三步要求,将应用密钥拼接到字符串T的尾末,得到字符串S如下。
app_id=10000&nonce_str=20e3408a79&text=%E8%85%BE%E8%AE%AF%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0&time_stamp=1493449657&app_key=a95eceb1ac8c24ee28b70f7dbba912bf 4\计算MD5摘要,得到签名字符串
依照算法第四步要求,对字符串S进行MD5摘要计算得到签名字符串如。
e8f6f347d549fe514f0c9c452c95da9d 5\转化md5签名值大写
对签名字符串所有字母进行大写转换,得到接口请求签名,结束算法。
E8F6F347D549FE514F0C9C452C95DA9D 6\最终请求数据
在完成签名计算后,即可得到所有接口请求数据,进一步完成API的调用。
text 腾讯开放平台 接口请求数据,UTF-8编码
app_id 10000 应用标识
time_stamp 1493449657 请求时间戳(秒级),用于防止请求重放
nonce_str 20e3408a79 请求随机字符串,用于保证签名不可预测
sign E8F6F347D549FE514F0C9C452C95DA9D 请求签名
'''
def gen_dict_md5(self,req_dict,app_key):
if not isinstance(req_dict,dict) :return None
if not isinstance(app_key,str) or not app_key:return None try:
#方法,先对字典排序,排序之后,写app_key,再urlencode
sort_dict= sorted(req_dict.items(), key=lambda item:item[0], reverse = False)
sort_dict.append(('app_key',app_key))
sha = hashlib.md5()
rawtext= urlencode(sort_dict).encode()
sha.update(rawtext)
md5text= sha.hexdigest().upper()
#print(1)
#字典可以在函数中改写
if md5text: req_dict['sign']=md5text
return md5text
except Exception as e:
return None #生成字典
def gen_req_dict(self, req_dict,app_id=None, app_key=None,time_stamp=None, nonce_str=None):
"""用MD5算法生成安全签名"""
if not req_dict.get('app_id'):
if not app_id: app_id= self.app_id
req_dict['app_id']= app_id #nonce_str 字典无值
if not req_dict.get('time_stamp'):
if not time_stamp: time_stamp= self.get_time_stamp()
req_dict['time_stamp']= time_stamp if not req_dict.get('nonce_str'):
if not nonce_str: nonce_str= self.get_random_str()
req_dict['nonce_str']= nonce_str
#app_key 取系统参数。
if not app_key: app_key= self.app_key
md5key= self.gen_dict_md5(req_dict, app_key)
return md5key
'''
基本文本分析
===========
分词 对文本进行智能分词识别,支持基础词与混排词粒度 https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordseg text
词性标注 对文本进行分词,同时为每个分词标注正确的词性 https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordpos text
专有名词识别 对文本进行专有名词的分词识别,找出文本中的专有名词 https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordner text
同义词识别 识别文本中存在同义词的分词,并返回相应的同义词 https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordsyn text 计算机视觉--OCR识别
====================
通用OCR识别 识别上传图像上面的字段信息 https://api.ai.qq.com/fcgi-bin/ocr/ocr_generalocr image
身份证OCR识别 识别身份证图像上面的详细身份信息 https://api.ai.qq.com/fcgi-bin/ocr/ocr_idcardocr image,card_type(身份证,0-正面,1-反面)
名片OCR识别 识别名片图像上面的字段信息 https://api.ai.qq.com/fcgi-bin/ocr/ocr_bcocr image
行驶证驾驶证OCR识别 识别行驶证或驾驶证图像上面的字段信息 https://api.ai.qq.com/fcgi-bin/ocr/ocr_driverlicenseocr image,type(识别类型,0-行驶证识别,1-驾驶证识别)
营业执照OCR识别 识别营业执照上面的字段信息 https://api.ai.qq.com/fcgi-bin/ocr/ocr_bizlicenseocr image
银行卡OCR识别 识别银行卡上面的字段信息 https://api.ai.qq.com/fcgi-bin/ocr/ocr_creditcardocr image
'''
#改成你自己的API账号、密码
APPID=''
APPKEY='UUUUUUUUU'
TencentAPI={
#基本文本分析API
"nlp_wordseg": {
'APINAME':'分词',
'APIDESC': '对文本进行智能分词识别,支持基础词与混排词粒度',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordseg',
'APIPARA': 'text'
},
"nlp_wordpos": {
'APINAME':'词性标注',
'APIDESC': '对文本进行分词,同时为每个分词标注正确的词性',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordpos',
'APIPARA': 'text'
},
'nlp_wordner': {
'APINAME':'专有名词识别',
'APIDESC': '对文本进行专有名词的分词识别,找出文本中的专有名词',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordner',
'APIPARA': 'text'
},
'nlp_wordsyn': {
'APINAME':'同义词识别',
'APIDESC': '识别文本中存在同义词的分词,并返回相应的同义词',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordsyn',
'APIPARA': 'text'
}, #计算机视觉--OCR识别API
"ocr_generalocr": {
'APINAME':'通用OCR识别',
'APIDESC': '识别上传图像上面的字段信息',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/ocr/ocr_generalocr',
'APIPARA': 'image'
},
"ocr_idcardocr": {
'APINAME':'身份证OCR识别',
'APIDESC': '识别身份证图像上面的详细身份信息',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/ocr/ocr_idcardocr',
'APIPARA': 'image,card_type'
},
"ocr_bcocr": {
'APINAME':'名片OCR识别',
'APIDESC': '识别名片图像上面的字段信息',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/ocr/ocr_bcocr',
'APIPARA': 'image'
},
"ocr_driverlicenseocr":{
'APINAME':'行驶证驾驶证OCR识别',
'APIDESC': '识别行驶证或驾驶证图像上面的字段信息',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/ocr/ocr_driverlicenseocr',
'APIPARA': 'image,type'
},
"ocr_bizlicenseocr":{
'APINAME':'营业执照OCR识别',
'APIDESC': '识别营业执照上面的字段信息',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/ocr/ocr_bizlicenseocr',
'APIPARA': 'image'
},
"ocr_creditcardocr":{
'APINAME':'银行卡OCR识别',
'APIDESC': '识别银行卡上面的字段信息',
'APIURL': 'https://api.ai.qq.com/fcgi-bin/ocr/ocr_creditcardocr',
'APIPARA': 'image'
},
} def ExecTecentAPI(*arg,**kwds):
if kwds.get('Apiname'): apiname= kwds.pop('Apiname') url = TencentAPI[apiname]['APIURL']
name = TencentAPI[apiname]['APINAME']
desc= TencentAPI[apiname]['APIDESC']
para= TencentAPI[apiname]['APIPARA'] tx= MsgTencent(APPID,APPKEY) Req_Dict={}
for key in para.split(','):
value=None
print (kwds)
if kwds.get(key): value = kwds.pop(key)
if key=='image':
#图像获取base64
value= tx.get_img_base64str(value)
if key=='text':
#文本进行GBK编码
value= value.encode('gbk') Req_Dict[key]=value
print (key,value,Req_Dict[key]) #生成请求包
sign= tx.gen_req_dict(req_dict=Req_Dict)
resp = requests.post(url,data=Req_Dict,verify=False)
print (name+'执行结果'+resp.text)
return resp.text if __name__ == "__main__":
#名片ocr
file= r'名片.jpg'
rest = ExecTecentAPI(Apiname='ocr_bcocr',image=file)
#文本分析
rest = ExecTecentAPI(Apiname='nlp_wordseg',text='上帝保佑你')
Python3 下实现 Tencent AI 调用的更多相关文章
- python3下调用系统massagebox对话框
#python3下调用系统massagebox对话框#先安装pwin32插件https://github.com/mhammond/pywin32/releases import win32apiim ...
- 论python3下“多态”与“继承”中坑
1.背景: 近日切换到python3后,发现python3在多态处理上,有一些比较有意思的情况,特别记载,供大家参考... 以廖老师的python3教程中的animal 和dog的继承一节的代码做例子 ...
- 在python3下用PIL做图像处理
Python Imaging Library (PIL)是python下的图像处理模块,支持多种格式,并提供强大的图形与图像处理功能. 目前PIL的官方最新版本为1.1.7,支持的版本为python ...
- iOS下的 Fixed + Input 调用键盘的时候fixed无效问题解决方案
做touchweb开发的时候,做头疼的是,电脑上面时候好的,有些手机上面也是好的,个别手机和浏览器出现问题,对于这些,只能慢慢调试,找问题. 今天说一下比较老的IOS的问题,那就是"iOS下 ...
- bugzilla4的xmlrpc接口api调用实现分享: xmlrpc + https + cookies + httpclient +bugzilla + java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能
xmlrpc . https . cookies . httpclient.bugzilla . java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能,网上针对bugzilla的实现很 ...
- Python3下map函数的显示问题
map函数是Python里面比较重要的函数,设计灵感来自于函数式编程.Python官方文档中是这样解释map函数的: map(function, iterable, ...) Return an it ...
- 解析android framework下利用app_process来调用java写的命令及示例
解析android framework下利用app_process来调用java写的命令及示例 在android SDK的framework/base/cmds目录下了,有不少目录,这些目的最终都是b ...
- python3下获取主流浏览器和python的安装路径
#coding=utf-8#python3下获取主流浏览器和python的安装路径#by dengpeiyou date:2018-07-09import winreg,os #取得浏览器的安装路径d ...
- 在python3下使用OpenCV 显示图像
在Python3下用使用OpenCV比在C,C++里开发不止快捷一点点, 原型开发的时候蛮有用. 这里用的OpenCV 加载图片, 用的imshow画图 # -*- coding: utf-8 -*- ...
随机推荐
- SQL Server数据转MySql
正好用到SQL Server数据转MySql的知识,就分享一下, 准备:需要用到 Navicat Premium 百度上下载就好 1.打开连接MySQL数据库,新建数据库,双击数据库点击导入 2.导 ...
- Linux入门(16)——Ubuntu16.04下配置sublime text 3使用markdown
sublime text 3安装两个插件: MarkDown Editing OmniMarkupPreviewer 有的人使用 MarkDown Editing markdownpreviewer ...
- Linux 快捷键汇总(偏基础)
自己最近才搭上Linux末班车,有一种想见恨晚的感觉,完全给你一种快速清爽的感觉! 因为需要,所以学习,记录自己在使用Linux系统上的点滴,偏基础! 1. 打开终端: Ctrl+Alt+T 2. 复 ...
- C#实现局域网内远程开机
1.远程开机原理 远程开机Wake on LAN(WOL),俗称远程唤醒,远程唤醒的实现主要是向目标主机发送特殊格式的数据包,是AMD公司制作的MagicPacket这套软件以生成网络唤醒所需要的特殊 ...
- 超级详细 一听就会:利用JavaScript jQuery实现图片无限循环轮播(不借助于轮播插件)
前言 作为一个前端工程师,无论公司是什么行业,无论你做什么端,基本都会遇到一个避不开的动画效果:循环轮播.做轮播并不难,市场上的轮播插件有很多,其中比较著名的是swiper,使用也非常简单.但轮播插件 ...
- Java 从键盘输入
package io; import java.io.*; public class ReadAndWrite { public static void main(String[] args) { I ...
- 大道至简第一章读后感Java伪代码
//一.愚公移山 /*原始需求 惩山北直塞,出入之迁也. 项目沟通的方式 聚室而谋 项目目标 毕力平险,指通豫南,达于汉阴 人员组成 愚公,子孙荷担者三夫,邻人遗男 技术方案 叩石垦壤 簸萁运与渤海之 ...
- 数据帧CRC32校验算法实现
本文设计思想采用明德扬至简设计法.由于本人项目需要进行光纤数据传输,为了保证通信质量要对数据进行校验.在校验算法中,最简单最成熟的非CRC校验莫属了. 得出一个数的CRC校验码还是比较简单的: 选定一 ...
- Spring Bean装配方式
Spring装配机制 在xml中进行显示配置 在Java中进行显示配置 隐式bean发现机制和自动装配 自动化装配bean 组件扫描(component scanning),Spring会自动发现应用 ...
- FastDFS与Nginx的配置说明
1.简介 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文件为载 ...