多次对比可知:
from,s,text,to是必要的变化参数
from(输入语种),text(输入),to(输出语种)就不必多说了,下面浅讲一下s是怎么来的,与如何使用Python得到它。
打开源代码,找到s生成的位置 (漫长~~),可以按Ctrl+Shift+F调出搜索功能,全局搜索's',也可以在所有的js文件中Ctrl+F搜索's'。
's'生成位置:top/search.sougoucdn.com/translate//pc//static/js/app.9b744a4e.js美观化后的第2962行 稍微往上看一下(2951行)会发现s就是 K.a.cal("".concat(p).concat(m).concat(l).concat(O))。
有一个Python第三方库叫execjs可以运行javascript脚本,牢记缺啥补啥大法 利用断点调试 将每一个需要的 函数 都复制到本地的一个(*.js)文件里。
嗯呐~~
感觉字数差不多了呐,直接上代码吧
本地的文件的结构差不多长这样:
Cookie.txt里装的是您登陆后的Cookie
JSON.js(名字瞎取的,js跟json没半毛钱关系)内容如下:
function rotl(t, n) {
return t << n | t >>> 32 - n
}
function crypt_endian(t){
if (t.constructor == Number)
return 16711935 & rotl(t, 8) | 4278255360 & rotl(t, 24);
for (let n = 0; n < t.length; n++)
t[n] = crypt_endian(t[n]);
return t
}
function _ff(t, n, r, e, o, i, u) {
const a = t + (n & r | ~n & e) + (o >>> 0) + u;
return (a << i | a >>> 32 - i) + n
}
function _gg(t, n, r, e, o, i, u) {
const a = t + (n & e | r & ~e) + (o >>> 0) + u;
return (a << i | a >>> 32 - i) + n
}
function _hh(t, n, r, e, o, i, u) {
const a = t + (n ^ r ^ e) + (o >>> 0) + u;
return (a << i | a >>> 32 - i) + n
}
function _ii(t, n, r, e, o, i, u) {
const a = t + (r ^ (n | ~e)) + (o >>> 0) + u;
return (a << i | a >>> 32 - i) + n
}
function crypt_bytesToWords(t) {
for (var n = [], r = 0, e = 0; r < t.length; r++,
e += 8)
n[e >>> 5] |= t[r] << 24 - e % 32;
return n
}
function isBuffer(t){
return null != t && (r(t) || function(t) {
return "function" == typeof t.readFloatLE && "function" == typeof t.slice && r(t.slice(0, 0))
}(t) || !!t._isBuffer)
}
function utf8_stringToBytes(t){
return bin_stringToBytes(unescape(encodeURIComponent(t)))
}
function bin_stringToBytes(t){
for (var n = [], r = 0; r < t.length; r++)
n.push(255 & t.charCodeAt(r));
return n
}
function crypt_wordsToBytes(t){
for (var n = [] , r = 0; r < 32 * t.length; r += 8)
n.push(t[r >>> 5] >>> 24 - r % 32 & 255);
return n
}
function md5(t ,n){
t.constructor == String ? t = n && "binary" === n.encoding ? bin_stringToBytes(t) : utf8_stringToBytes(t) : isBuffer(t) ? t = Array.prototype.slice.call(t , 0) : Array.isArray(t) || (t = t.toString());
const r = crypt_bytesToWords(t)
, e = 8 * t.length;
let o = 1732584193
, i = -271733879
, u = -1732584194
, a = 271733878;
for (var c = 0; c < r.length; c++)
r[c] = 16711935 & (r[c] << 8 | r[c] >>> 24) | 4278255360 & (r[c] << 24 | r[c] >>> 8);
r[e >>> 5] |= 128 << e % 32 ,
r[14 + (e + 64 >>> 9 << 4)] = e;
const f = _ff
, s = _gg
, l = _hh
, h = _ii;
for (c = 0; c < r.length; c += 16) {
const t = o
, n = i
, e = u
, p = a;
o = f(o , i , u , a , r[c + 0] , 7 , -680876936) ,
a = f(a , o , i , u , r[c + 1] , 12 , -389564586) ,
u = f(u , a , o , i , r[c + 2] , 17 , 606105819) ,
i = f(i , u , a , o , r[c + 3] , 22 , -1044525330) ,
o = f(o , i , u , a , r[c + 4] , 7 , -176418897) ,
a = f(a , o , i , u , r[c + 5] , 12 , 1200080426) ,
u = f(u , a , o , i , r[c + 6] , 17 , -1473231341) ,
i = f(i , u , a , o , r[c + 7] , 22 , -45705983) ,
o = f(o , i , u , a , r[c + 8] , 7 , 1770035416) ,
a = f(a , o , i , u , r[c + 9] , 12 , -1958414417) ,
u = f(u , a , o , i , r[c + 10] , 17 , -42063) ,
i = f(i , u , a , o , r[c + 11] , 22 , -1990404162) ,
o = f(o , i , u , a , r[c + 12] , 7 , 1804603682) ,
a = f(a , o , i , u , r[c + 13] , 12 , -40341101) ,
u = f(u , a , o , i , r[c + 14] , 17 , -1502002290) ,
i = f(i , u , a , o , r[c + 15] , 22 , 1236535329) ,
o = s(o , i , u , a , r[c + 1] , 5 , -165796510) ,
a = s(a , o , i , u , r[c + 6] , 9 , -1069501632) ,
u = s(u , a , o , i , r[c + 11] , 14 , 643717713) ,
i = s(i , u , a , o , r[c + 0] , 20 , -373897302) ,
o = s(o , i , u , a , r[c + 5] , 5 , -701558691) ,
a = s(a , o , i , u , r[c + 10] , 9 , 38016083) ,
u = s(u , a , o , i , r[c + 15] , 14 , -660478335) ,
i = s(i , u , a , o , r[c + 4] , 20 , -405537848) ,
o = s(o , i , u , a , r[c + 9] , 5 , 568446438) ,
a = s(a , o , i , u , r[c + 14] , 9 , -1019803690) ,
u = s(u , a , o , i , r[c + 3] , 14 , -187363961) ,
i = s(i , u , a , o , r[c + 8] , 20 , 1163531501) ,
o = s(o , i , u , a , r[c + 13] , 5 , -1444681467) ,
a = s(a , o , i , u , r[c + 2] , 9 , -51403784) ,
u = s(u , a , o , i , r[c + 7] , 14 , 1735328473) ,
i = s(i , u , a , o , r[c + 12] , 20 , -1926607734) ,
o = l(o , i , u , a , r[c + 5] , 4 , -378558) ,
a = l(a , o , i , u , r[c + 8] , 11 , -2022574463) ,
u = l(u , a , o , i , r[c + 11] , 16 , 1839030562) ,
i = l(i , u , a , o , r[c + 14] , 23 , -35309556) ,
o = l(o , i , u , a , r[c + 1] , 4 , -1530992060) ,
a = l(a , o , i , u , r[c + 4] , 11 , 1272893353) ,
u = l(u , a , o , i , r[c + 7] , 16 , -155497632) ,
i = l(i , u , a , o , r[c + 10] , 23 , -1094730640) ,
o = l(o , i , u , a , r[c + 13] , 4 , 681279174) ,
a = l(a , o , i , u , r[c + 0] , 11 , -358537222) ,
u = l(u , a , o , i , r[c + 3] , 16 , -722521979) ,
i = l(i , u , a , o , r[c + 6] , 23 , 76029189) ,
o = l(o , i , u , a , r[c + 9] , 4 , -640364487) ,
a = l(a , o , i , u , r[c + 12] , 11 , -421815835) ,
u = l(u , a , o , i , r[c + 15] , 16 , 530742520) ,
i = l(i , u , a , o , r[c + 2] , 23 , -995338651) ,
o = h(o , i , u , a , r[c + 0] , 6 , -198630844) ,
a = h(a , o , i , u , r[c + 7] , 10 , 1126891415) ,
u = h(u , a , o , i , r[c + 14] , 15 , -1416354905) ,
i = h(i , u , a , o , r[c + 5] , 21 , -57434055) ,
o = h(o , i , u , a , r[c + 12] , 6 , 1700485571) ,
a = h(a , o , i , u , r[c + 3] , 10 , -1894986606) ,
u = h(u , a , o , i , r[c + 10] , 15 , -1051523) ,
i = h(i , u , a , o , r[c + 1] , 21 , -2054922799) ,
o = h(o , i , u , a , r[c + 8] , 6 , 1873313359) ,
a = h(a , o , i , u , r[c + 15] , 10 , -30611744) ,
u = h(u , a , o , i , r[c + 6] , 15 , -1560198380) ,
i = h(i , u , a , o , r[c + 13] , 21 , 1309151649) ,
o = h(o , i , u , a , r[c + 4] , 6 , -145523070) ,
a = h(a , o , i , u , r[c + 11] , 10 , -1120210379) ,
u = h(u , a , o , i , r[c + 2] , 15 , 718787259) ,
i = h(i , u , a , o , r[c + 9] , 21 , -343485551) ,
o = o + t >>> 0 ,
i = i + n >>> 0 ,
u = u + e >>> 0 ,
a = a + p >>> 0
}
return crypt_endian([o , i , u , a])
}
function crypt_bytesToHex(t) {
for (var n = [] , r = 0; r < t.length; r++)
n.push((t[r] >>> 4).toString(16)) ,
n.push((15 & t[r]).toString(16));
return n.join("")
}
function cal(t , n){
if (null == t)
throw new Error(`Illegal argument ${t}`);
const r = crypt_wordsToBytes(md5(t , n));
return n && n.asBytes ? r : n && n.asString ? bin_bytesToString(r) : crypt_bytesToHex(r)
}
Sougou_Translate_API.py内容如下:(25行与52行需要补充哦)
import requests;import execjs;import json
class Sougou_Translate_API():
def __init__(self, word, _from_, _to_):
'''
zh-CHS(汉语), en(英语), ar(阿拉伯语),
pl(波兰语), da(丹麦语), de(德语),
ru(俄语), fr(法语), fi(芬兰语),
ko(韩语), nl(荷兰语), cs(捷克语),
pt(葡萄牙语), ja(日语), sv(瑞典语),
th(泰语), tr(土耳其语), es(西班牙语),
hu(匈牙利语), it(意大利语), vi(越南语)
'''
self.word = word
self._from_ = _from_
self._to_ = _to_
self.url = 'https://fanyi.sogou.com/api/transpc/text/result'
self.Cookie = self.get_Cookie()
self.headers = {
'Content-Type': 'application/json;charset=UTF-8',
'Cookie': self.Cookie,
'User-Agent': '您的User-Agent'
}
self.s = self.get_s()
self.uuid = 'a9d37792-8b7b-4428-be78-929f4d67f23f'#没有啥特别影响的参数直接找一个就行
self.data = {
"from":_from_,
"to":_to_,
"text":self.word,
"client":"pc",
"fr":"browser_pc",
"needQc":1,
"s":self.s,
"uuid":self.uuid,
"exchange": 'true'#也可以是'false'
}
r = requests.post(url=self.url, data=json.dumps(self.data), headers=self.headers)
self.response = r.json()
def get_Cookie(self):
with open('Cookie.txt', 'r') as f:
Cookie = f.read()
return Cookie
def get_s(self):
t = self._from_+self._to_+self.word+"您的秘密代码"#断一下点,自己去找
with open('JSON.js', encoding='utf-8') as f:
js =f.read()
ctx = execjs.compile(js)
result = ctx.call('cal',t)#调用JSON.js里的cal函数
return result
def result(self):#翻译结果
return self.response['data']['translate']['dit']
def film_example(self):#影视原声
book = self.response['data']['book']
if bool(book):
return None
else:
return book
def bilingual_example(self):#双语例句
know = self.response['data']['detail']
if bool(know):
return None
else:
if 'bilingual' in know:
return know["bilingual"]
def entry(self):#百科知识
know = self.response['data']['detail']
if bool(know):
return None
else:
if 'baike' in know:
return know["baike"]["list"]
def word_group(self):#词组
know = self.response['data']['detail']
if bool(know):
return None
else:
if 'word_group' in know:
wg = know["word_group"]
ret = []
for i in wg:
ret.append([i["brief_definition"],i["phrase"]])
return ret
def slef_info(self):#输入文本的信息
return {"detect":self.response["data"]["detect"]["detect"],"language":self.response["data"]["detect"]["language"]}
def voice(self):#输入文本的读音
return self.response["data"]["voice"]
---------------------------------------------------------------------------------------------------------------------------------
现在上面的链接中的文件夹中找到适合自己的版本(我的电脑是Windows7(64位),下面是我的方法)
点击红箭头指的那个
打勾的是可以选的(位数不同,因人而异),我则是点击箭头所指的压缩包(7z比zip压缩的更小,内容一样哒),下载好后,把这个压缩包移到OK的地方解压(D://),最后设置Path
上图波浪线画出的Path十分珍贵,所以必要的话可以复制备份
在原Path后小心的加上一个分号‘;’,然后加上node文件夹的地址(上上图),最后一次确定即可。
下面测试一下:
>>>import execjs
>>>execjs.get().name
'Node.JS(U8)'
>>>print('OK啦!')
OK啦!