python翻译接口测试(3)-最终篇

经过了前一篇的博客启发,我们如果想要实现百度翻译,还需要搞清楚sign的值是从何而来的,搬好小板凳,开始上教程!

第一步

翻译结果出来后我们打开开发者工具(或者按F12),然后按“Ctrl+Shift+F”进行全局搜索,搜索关键字“sign”,搜索出来后点击打开

点击下方的标志可以格式化代码 

第二步

我们现在还不知道这个sign:y(a)是什么意思,我们就打上断点调试一下,浏览器调试代码方法请自行百度。

 

刷新页面重新进行翻译,调试到这行代码之后,我们把鼠标放在这里,可以看到a的值就是我们输入的要查询的单词 ,sign的值很可能就是由函数y产生的,那么y是什么呢?我们把鼠标放到y上面,就可以看到y的函数主体部分,鼠标点击就可以进去这个函数主体

函数主体部分的代码如下:

function e(r) {
    var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
    if (null === o) {
        var t = r.length;
        t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10))
    } else {
        for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++)
            "" !== e[C] && f.push.apply(f, a(e[C].split(""))),
            C !== h - 1 && f.push(o[C]);
        var g = f.length;
        g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join(""))
    }
    var u = void 0,
        l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107);
    u = null !== i ? i : (i = window[l] || "") || "";
    for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) {
        var A = r.charCodeAt(v);
        128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)),
                    S[c++] = A >> 18 | 240,
                    S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224,
                S[c++] = A >> 6 & 63 | 128),
            S[c++] = 63 & A | 128)
    }
    for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++)
        p += S[b],
        p = n(p, F);
    return p = n(p, D),
        p ^= s,
        0 > p && (p = (2147483647 & p) + 2147483648),
        p %= 1e6,
        p.toString() + "." + (p ^ m)
}

第三步

我们把这份js代码另存为fun_e(r).js,然后利用Python的PyExecJS库调试运行下这段js代码(需要提前装好node.js环境)

import execjs
# print(execjs.get().name) # 输出所用环境名称
with open("pytest\翻译接口\\fun_e(r).js", "r", encoding='utf-8') as f:
    ctx = execjs.compile(f.read())
print(ctx.call("e", "我是大帅哥"))

但是运行后提示变量i没有被定义

我们返回到浏览器,找到i,同样的打上断点,这里我给变量u也打上断点了,方便看变量u值的变化,跟上面一样,调试后可以看到i的值为"320305.131321201"

这时,我们还不能确定i的值是不是就是"320305.131321201",我们换个词重新进行翻译调试,经过多次试验,i的值固定不变,我们可以确定i的值就是"320305.131321201"(字符串类型)

第四步

我们在之前建好的js文件中定义一个i变量并赋值

重新调试运行又提示n没有被定义

我们故技重施,返回浏览器搜索到n,打断点调试,可以找到n的函数主体

我们把这段代码复制下来放到js文件里面的前面,重新运行代码

得到sign值!(不确定是不是sign值的话就在浏览器中搜索相同的词,看看提交表单的sign值是不是一样,换词多次试验可以确定这个就是sign值)

完整的js代码如下

function n(r, o) {
    for (var t = 0; t < o.length - 2; t += 3) {
        var a = o.charAt(t + 2);
        a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a),
            a = "+" === o.charAt(t + 1) ? r >>> a : r << a,
            r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a
    }
    return r
}

function e(r) {
    var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
    if (null === o) {
        var t = r.length;
        t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10))
    } else {
        for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++)
            "" !== e[C] && f.push.apply(f, a(e[C].split(""))),
            C !== h - 1 && f.push(o[C]);
        var g = f.length;
        g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join(""))
    }
    var i = "320305.131321201";
    var u = void 0,
        l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107);
    u = null !== i ? i : (i = window[l] || "") || "";
    for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) {
        var A = r.charCodeAt(v);
        128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)),
                    S[c++] = A >> 18 | 240,
                    S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224,
                S[c++] = A >> 6 & 63 | 128),
            S[c++] = 63 & A | 128)
    }
    for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++)
        p += S[b],
        p = n(p, F);
    return p = n(p, D),
        p ^= s,
        0 > p && (p = (2147483647 & p) + 2147483648),
        p %= 1e6,
        p.toString() + "." + (p ^ m)
}

第五步

既然如何获取sign值了,那么百度翻译也就搞定啦,奉上完整代码

# 破解sign值
import requests
import re
import execjs 
import json

headers = {
    "User-Agent":
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
    'Cookie':
        'PSTM=1575539987; BAIDUID=A80872D93185A688C8AC8CF159A4EF54:FG=1; BIDUPSID=3D8B9E5934B26CCEF003426B6773A431; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_PS_PSSID=1455_21114_26350_30717; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; APPGUIDE_8_2_2=1; from_lang_often=%5B%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D; to_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1580901474,1580904731,1580905304,1580906217; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1580906217; yjs_js_security_passport=0fdd751f0722a3d0fb6a389e7fe2c2f2c9864c58_1580906237_js; __yjsv5_shitong=1.0_7_4a4fb445c2fea6132d704ca5e45285f82f61_300_1580906238325_223.91.220.158_37acdb4d; delPer=0; PSINO=1'
}

form_data = {
    # 'from': 'zh',
    # 'to': 'en',
    # 'query': word,
    'transtype': 'realtime',
    'simple_means_flag': '3',
    # 'sign': None,
    'token': '42e08df4cfc832413f5c96516ed21cc3'
}

# 获取sign的值
def getSign(word):
    with open('pytest\翻译接口\\fun_e(r).js', 'r', encoding='utf-8') as f:
        sign_js = execjs.compile(f.read())
        return sign_js.call('e', word)

# 获取结果的json数据
def getResult(url):
    try:
        r = requests.post(url, data=form_data, headers=headers, timeout=30)
        r.raise_for_status
        return r.text
    except:
        return ''
# 主函数
print("本程序同时支持汉译英和英译汉")
print("汉译英请输入1,英译汉请输入其他非0数字")
print("若想终止程序,请输入0")
while(True):
    a = eval(input("请输入数字:"))
    if a == 1:
        f = 'zh'
        t = 'en'
    elif a==0:
        break
    else:
        f = 'en'
        t = 'zh'
    url_post = "https://fanyi.baidu.com/v2transapi"
    word = input("请输入要查询的字符:")
    sign = getSign(word)
    form_data['from'] = f
    form_data['to'] = t
    form_data['query'] = word
    form_data['sign'] = sign
    text = getResult(url_post)
    json_data = json.loads(text)
    # print(json_data)
    trans_result = json_data['trans_result']['data'][0]['dst']
    # print(trans_result)
    print("{}的翻译是:{}".format(word, trans_result))
print("程序退出运行!")

运行结果如下

发布了143 篇原创文章 · 获赞 78 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/KK_2018/article/details/104327372