百度翻译接口加密法

前言

前些天,为了完善我的项目 GKF 的一个 翻译 类,我注册了百度翻译接口 API,结果比平时一些接口复杂的请求操作倒是立刻迷上了我。之前我用过别人公开的免费接口:类似 VIP 解析、查天气、随机一句话之类的接口,都是直接在接口:http(s)://domain_name/api_path/?parameter_name= 的等于号后面直接输入实参,就可以通过 get 的方式获取返回的数据(百度返回的是 JSON 字典)。而百度获取内容前的加密方案就足以让我这种平时想白嫖接口的人望而却步了。

正好我正在学习 Python ,就边结合者代码讲解一下。

官方给的通用型(我申请的是通用型的,专业型既可自定义翻译内容的和尊贵型的要马内,搞不起)文档:https://api.fanyi.baidu.com/doc/21, 第一次看时,差点从入手到放弃;第二次,开始看得懂,并一步步敲起代码(失败);直到下载了官方的 Python demos,一切才开始在我脑里理清楚。


关于接口申请

官方给了以下提示:

如何使用通用翻译API?

  1. 使用您的百度账号登录百度翻译开放平台
  2. 注册成为开发者,获得 APPID ;
  3. 进行开发者认证(如仅需标准版可跳过);
  4. 开通通用翻译API服务:开通链接
  5. 参考技术文档和 Demo 编写代码。

总结成一句话:跟你一点屁事都没有(但对我有用)

不过这个地方还是值得说一说的,一般申请完后,会给你一个专属的 appid , 每个 appid 还对应着一个 appkey 。换句话说就是帮你设置好了账号名和密码(appid 不可更改,appkey 如果 泄露可以点击“密钥充值”),其中 appid 全是数字(即使这样,在使用的时候还是得将其转换为字符串),appkey 则是英文大小写混合组合。下面是我的相关信息(别想白嫖)


参数说明

appkey 在请求的时候不用输入,但是在服务端(百度),有一个数据库,里面放着所有的 appid 和 appkey ,在请求 appid 时会自动调用相对应的 appkey,为后面的加密做准备。

这时,服务端获取完了所需参数:appid、query(请求翻译的内容)、salt(一个随机数,这是将加密升级的方案,在数字键随便敲一个数字就行,不限位数。好像是可以用字符串的)、appkey(请求时不用输入),然后就对这一串内容进行 MD5 值计算,并将其与我们请求时所计算的 MD5 值进行比较(请将此值的相对变量名命名为 sign ,即签名,官方时这么规定的)。

相关内容所需导入库及其作用如下:

import requests  # 模拟浏览器进行请求
from hashlib import md5  # 方便在程序内进行 MD5 值的计算
from random import randint  # 方便生成自定义范围内的随机数

下面是官方关于签名(sign)生成的介绍

签名生成方法

签名是为了保证调用安全,使用 MD5 算法生成的一段字符串,生成的签名长度为 32 位,签名中的英文字符均为小写格式。

生成方法:

Step1. 将请求参数中的 APPID(appid), 翻译 query(q,注意为UTF-8编码),随机数(salt),以及平台分配的密钥(可在管理控制台查看) 按照 appid+q+salt+密钥的顺序拼接得到字符串 1。
Step2. 对字符串 1 做 md5 ,得到 32 位小写的 sign。

注:

  1. 待翻译文本(q)需为 UTF-8 编码;
  2. 在生成签名拼接 appid+q+salt+密钥 字符串时,q 不需要做 URL encode,在生成签名之后,发送 HTTP 请求之前才需要对要发送的待翻译文本字段 q 做 URL encode;
  3. 如遇到报 54001 签名错误,请检查您的签名生成方法是否正确,在对 sign 进行拼接和加密时,q 不需要做 URL encode,很多开发者遇到签名报错均是由于拼接 sign 前就做了 URL encode;
  4. 在生成签名后,发送 HTTP 请求时,如果将 query 拼接在 url 上,需要对 query 做 URL encode。

说这么多屁话,简单说就是:

salt = randint(1,99999999999999)  # 生成随机数,参数可改

s = appid + query + str(salt) + appkey
sign = md5(s.encode(encoding)).hexdigest()  # 生成签名,并赋值给变量 sign,方便后面调用

Get & 处理数据

把东西整好,开始用 requests 进行 get:

官方给的请求示例

http://api.fanyi.baidu.com/api/trans/vip/translate?q=apple&from=en&to=zh&appid=2015063000000001&salt=1435660288&sign=f89f9594663708c1605f3d736d01d2d4

转换为程序接收参数的变量值并get:

get_url = 'http://api.fanyi.baidu.com/api/trans/vip/translate?q=' + query + '&from=auto&to=zh&appid=' + appid + '&salt=' + str(salt) + '&sign=' + sign
get = requests.get(get_url)

服务端处理数据,并比较 sign ,成功:

处理返回数据:

result = get.json()

返回结果(假设提交的 query 的实参为“apple”):

{
    "from": "en", 
    "to": "zh", 
    "trans_result": [
        {
            "src": "apple", 
            "dst": "苹果"
        }
    ]
}

选取核心:

print("Trans result:" + result['trans_result'][0]['dst'])

输出:

Trans result:苹果

使用有感

关于处理返回数据的内容其实并不重要,核心是加密算法,用这种多维的加密方式,可以大大减小资源浪费(为防止机器而已爬取,也在一定程度上避免了对开发者的财产带来危险),从而给真正需要的用户提供更好的服务。

封装成类

# 导入必要的库
--snip--
class BaiduTranslate():
    def __init__(self,query = 'No input..',appid = '20211218001031865',appkey = 'OtZbXyAdRHL*********'):
        self.appid = appid
        self.appkey = appkey
        self.q = query
    # 下面封装两个方法,分别翻译日常常用语言(对于中国人来说)
    def en(self):  # 把任意语言翻译作英文
        salt = randint(1,100000000000)
        get_url = 'http://api.fanyi.baidu.com/api/trans/vip/translate?q=' + self.q + '&from=auto&to=en&appid=' + self.appid + '&salt=' + str(salt) + '&sign=' + sign
        get = requests.get(get_url)
        result = get.json()
        trans_result = result['trans_result'][0]['dst']
        return trans_result
    def zh(self):  # 把任意语言翻译作中文
        salt = randint(1,100000000000)
        get_url = 'http://api.fanyi.baidu.com/api/trans/vip/translate?q=' + self.q + '&from=auto&to=zh&appid=' + self.appid + '&salt=' + str(salt) + '&sign=' + sign
        get = requests.get(get_url)
        result = get.json()
        trans_result = result['trans_result'][0]['dst']
        return trans_result

使用方法

x = BaiduTranslate("老子天下第一")
print(x.en())
y = BaiduTranslate("Stop involution")
print(y.zh())

附上原GKF模块终端运行结果:(类和函数内容略有不同)

运行结果

版权声明:
作者:灰尘疾客
链接:https://www.gkcoll.xyz/92.html
来源:极客藏源
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>