Python3 下實現 騰訊人工智能API 調用


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=10000&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 = '1111111111'
        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='1111111111'
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='上帝保佑你')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM