• 爬虫 — Js 逆向案例一英汉互译


    目标网站:https://fanyi.baidu.com/

    需求:实现英汉互译

    案例分析

    1、分析网站加载方式

    动态加载,目标 url:https://fanyi.baidu.com/v2transapi?from=en&to=zh

    2、分析请求方式

    post(携带 data 参数)

    // 英译汉还是汉译英
    from: en
    to: zh
    query: hello // 查询的内容,变化的,可以决定
    transtype: realtime // 没有变化
    simple_means_flag: 3 // 没有变化
    sign: 54706.276099 // 会变化,⼀个单词⼀个数据
    token: e1aca5af9de730135e0dba1cea1af143 // 没有变化
    domain: common // 没有变化
    ts: 1687238388787 // 时间戳
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    多抓几个包看数据变化

    会产生变化并且必不可少的参数:sign 加密字段

    3、根据加密字段找和它相关的 js 文件

    按 F12 打开开发者工具,找到 Search,点击

    在这里插入图片描述

    4、在搜索框输入加密参数后,按回车

    在这里插入图片描述

    5、寻找与加密参数相关的 js 文件

    在这里插入图片描述

    6、给所有看起来和加密参数相关的都打上断点

    在这里插入图片描述

    7、加好所有断点后,重新输入内容进行翻译,查看跳转位置的代码是否是需要的代码

    在这里插入图片描述

    8、找到了 post 需要携带的相关参数后,新建一个 Js 文件,将找到的数据复制进去

    // baidu.js
    // 定义了一个函数,传递的参数是需要翻译的内容
    function b(e){
        // 返回数据
        return {
            from: b.fromLang,
            to: b.toLang,
            query: e,
            transtype: i,
            simple_means_flag: 3,
            sign: w(e),
            token: window.common.token,
            domain: x.getCurDomain(),
            ts: +new Date
        }
    }
    console.log(b('hello'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    9、运行后报错

            transtype: i,
                       ^
    
    ReferenceError: i is not defined
    
    • 1
    • 2
    • 3
    • 4

    10、找到浏览器中传递的数据,根据第2步的分析,调整代码

    在这里插入图片描述

    11、调整后的代码

    // baidu.js
    // 定义了一个函数,传递的参数是需要翻译的内容
    function b(e){
        // 返回数据
        return {
            from: 'en',
            to: 'zh',
            query: e,
            transtype: 'realtime',
            simple_means_flag: 3,
            sign: w(e),
            token: 'e1aca5af9de730135e0dba1cea1af143',
            domain: 'common',
            ts: +new Date
        }
    }
    console.log(b('hello'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    12、运行后报错

            sign: w(e),
                  ^
    
    ReferenceError: w is not defined
    
    • 1
    • 2
    • 3
    • 4

    13、需要到浏览器中寻找 w 函数

    在这里插入图片描述

    14、将跳转后的函数代码复制下来

    在这里插入图片描述

    15、将复制的代码粘贴到 Js 文件中,给函数添加上函数名称

    // baidu.js
    function w(t) {
        var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
        if (null === i) {
            var a = t.length;
            a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))
        } else {
            for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, l = s.length, u = []; c < l; c++)
                "" !== s[c] && u.push.apply(u, function(t) {
                    if (Array.isArray(t))
                        return e(t)
                }(o = s[c].split("")) || function(t) {
                    if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])
                        return Array.from(t)
                }(o) || function(t, n) {
                    if (t) {
                        if ("string" == typeof t)
                            return e(t, n);
                        var r = Object.prototype.toString.call(t).slice(8, -1);
                        return "Object" === r && t.constructor && (r = t.constructor.name),
                        "Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0
                    }
                }(o) || function() {
                    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
                }()),
                c !== l - 1 && u.push(i[c]);
            var p = u.length;
            p > 30 && (t = u.slice(0, 10).join("") + u.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + u.slice(-10).join(""))
        }
        for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = window[d] || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
            var _ = t.charCodeAt(v);
            _ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),
            g[y++] = _ >> 18 | 240,
            g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,
            g[y++] = _ >> 6 & 63 | 128),
            g[y++] = 63 & _ | 128)
        }
        for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)
            b = n(b += g[x], w);
        return b = n(b, k),
        (b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
        "".concat((b %= 1e6).toString(), ".").concat(b ^ f)
    }
    // 定义了一个函数,传递的参数是需要翻译的内容
    function b(e){
        // 返回数据
        return {
            from: 'en',
            to: 'zh',
            query: e,
            transtype: 'realtime',
            simple_means_flag: 3,
            sign: w(e),
            token: 'e1aca5af9de730135e0dba1cea1af143',
            domain: 'common',
            ts: +new Date
        }
    }
    console.log(b('hello'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    16、运行后报错

        for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = window[d] || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
                                                                                                                                ^
    
    ReferenceError: r is not defined
    
    • 1
    • 2
    • 3
    • 4

    17、分析 r 为一个值,可以给 r 赋值为 null

    // baidu.js
    var r = null
    
    • 1
    • 2

    18、运行后报错

        for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = window[d] || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
                                                                                                                                                       ^
    
    ReferenceError: window is not defined
    
    • 1
    • 2
    • 3
    • 4

    19、到浏览器中查看 window 是什么

    在这里插入图片描述

    20、获取到 window[d] 的值后,多次重新输入翻译内容,再运行确定值是否是固定的

    方式一:

    鼠标悬停显示

    在这里插入图片描述

    方式二:

    在控制台打印

    在这里插入图片描述

    21、确定 window[d] 为固定值后,将 Js 代码中的 window[d] 直接替换为固定值

    // baidu.js
    var r = null
    function w(t) {
        var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
        if (null === i) {
            var a = t.length;
            a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))
        } else {
            for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, l = s.length, u = []; c < l; c++)
                "" !== s[c] && u.push.apply(u, function(t) {
                    if (Array.isArray(t))
                        return e(t)
                }(o = s[c].split("")) || function(t) {
                    if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])
                        return Array.from(t)
                }(o) || function(t, n) {
                    if (t) {
                        if ("string" == typeof t)
                            return e(t, n);
                        var r = Object.prototype.toString.call(t).slice(8, -1);
                        return "Object" === r && t.constructor && (r = t.constructor.name),
                        "Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0
                    }
                }(o) || function() {
                    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
                }()),
                c !== l - 1 && u.push(i[c]);
            var p = u.length;
            p > 30 && (t = u.slice(0, 10).join("") + u.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + u.slice(-10).join(""))
        }
        for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = '320305.131321201' || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
            var _ = t.charCodeAt(v);
            _ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),
            g[y++] = _ >> 18 | 240,
            g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,
            g[y++] = _ >> 6 & 63 | 128),
            g[y++] = 63 & _ | 128)
        }
        for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)
            b = n(b += g[x], w);
        return b = n(b, k),
        (b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
        "".concat((b %= 1e6).toString(), ".").concat(b ^ f)
    }
    // 定义了一个函数,传递的参数是需要翻译的内容
    function b(e){
        // 返回数据
        return {
            from: 'en',
            to: 'zh',
            query: e,
            transtype: 'realtime',
            simple_means_flag: 3,
            sign: w(e),
            token: 'e1aca5af9de730135e0dba1cea1af143',
            domain: 'common',
            ts: +new Date
        }
    }
    console.log(b('hello'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    22、运行后报错

            b = n(b += g[x], w);
            ^
    
    ReferenceError: n is not defined
    
    • 1
    • 2
    • 3
    • 4

    23、找到函数 n 的来源

    在这里插入图片描述

    24、复制函数 n 的代码

    在这里插入图片描述

    25、将复制的代码粘贴到 Js 文件中

    // baidu.js
    var r = null
    function n(t, e) {
        for (var n = 0; n < e.length - 2; n += 3) {
            var r = e.charAt(n + 2);
            r = "a" <= r ? r.charCodeAt(0) - 87 : Number(r),
            r = "+" === e.charAt(n + 1) ? t >>> r : t << r,
            t = "+" === e.charAt(n) ? t + r & 4294967295 : t ^ r
        }
        return t
    }
    function w(t) {
        var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
        if (null === i) {
            var a = t.length;
            a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))
        } else {
            for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, l = s.length, u = []; c < l; c++)
                "" !== s[c] && u.push.apply(u, function(t) {
                    if (Array.isArray(t))
                        return e(t)
                }(o = s[c].split("")) || function(t) {
                    if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])
                        return Array.from(t)
                }(o) || function(t, n) {
                    if (t) {
                        if ("string" == typeof t)
                            return e(t, n);
                        var r = Object.prototype.toString.call(t).slice(8, -1);
                        return "Object" === r && t.constructor && (r = t.constructor.name),
                        "Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0
                    }
                }(o) || function() {
                    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
                }()),
                c !== l - 1 && u.push(i[c]);
            var p = u.length;
            p > 30 && (t = u.slice(0, 10).join("") + u.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + u.slice(-10).join(""))
        }
        for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = '320305.131321201' || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
            var _ = t.charCodeAt(v);
            _ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),
            g[y++] = _ >> 18 | 240,
            g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,
            g[y++] = _ >> 6 & 63 | 128),
            g[y++] = 63 & _ | 128)
        }
        for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)
            b = n(b += g[x], w);
        return b = n(b, k),
        (b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
        "".concat((b %= 1e6).toString(), ".").concat(b ^ f)
    }
    // 定义了一个函数,传递的参数是需要翻译的内容
    function b(e){
        // 返回数据
        return {
            from: 'en',
            to: 'zh',
            query: e,
            transtype: 'realtime',
            simple_means_flag: 3,
            sign: w(e),
            token: 'e1aca5af9de730135e0dba1cea1af143',
            domain: 'common',
            ts: +new Date
        }
    }
    console.log(b('hello'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    26、运行后返回结果

    {
      from: 'en',
      to: 'zh',
      query: 'hello',
      transtype: 'realtime',
      simple_means_flag: 3,
      sign: '54706.276099',
      token: 'e1aca5af9de730135e0dba1cea1af143',
      domain: 'common',
      ts: 1687239404824
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    27、编写 Python 代码

    # 百度翻译.py
    # 导入 requests 库,用于发送 HTTP 请求和处理 HTTP 响应
    import requests
    # 导入自定义模块,用于获取 JavaScript 代码生成的字典
    from JsReverse import get_js # JsReverse 为文件名,get_js 为函数名
    
    # 输入需要翻译的内容
    trs = input('请输入需要翻译的内容')
    # 调用 get_js 函数,传入 JavaScript 文件名'baidu.js'、函数名'b'和翻译内容 trs,获取生成的字典
    dic = get_js('baidu.js', 'b', trs)
    # 判断输入的是中文还是英文
    length = len(trs[0].encode('utf-8')) # 第一个字符长度,一个字母长度是为1,汉字是为3
    # 英文
    if length == 1:
        dic['from'] = 'en'
        dic['to'] = 'zh'
    # 中文
    elif length == 3:
        dic['from'] = 'zh'
        dic['to'] = 'en'
    # 打印字典
    # print(dic)
    # 设置翻译请求的 url
    url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'
    # 请求头
    headers = {
        'Acs-Token': '1687238994011_1687238994248_sKfCKQnOqNJPstsgIsKUPaqAYGqQnIFYiRYGiFYQlIQ+uev26ckgDP84N0sc9iBWm9m8CkW2nyiEwf2Nkr+8bGpHXAxRIArLKohyWWLDQsf6T3mPhsnt8wAI2EGbiEU21zkMCz4WHc49JrKS39GQphWRFrR6Rxu32HgHkqnebW3T7XKVJoRr3x55dGur43olklcdMSq7TOpNx9FDNL4i4dYpDyyjBJohySeR1BWbSHqJWo+IdOOFpNNz2ICr2jA3ngsBPByzUlk0Nr2zDVRfGfGeiZaMPd6BQbMLHVrU0cs8PX452MbNggwOVkN8cYPHGaXQOokzUAy13RMZtRRSqREFq+6oAk0evXXiHPAiGRRADoUYiwpYfKmw5k2nTISu5EpqTXOw/RlicgaHqgP+ubTc8EJ4QzCnBLMWDop+04+P0Ntzy0ngGRfdibhJ3ChIHbQQx+Ner2JCsrTlglUYfIT2Cw4VMvdc2ItaV3MAC2dt0cn7NK2ZLK933nMOwspa',
        'Cookie': 'BIDUPSID=B7CB7F26DDDA7D98FF29C3EEC2AFEE2E; PSTM=1682489485; BAIDUID=B7CB7F26DDDA7D988547B56FBC007491:FG=1; BAIDUID_BFESS=B7CB7F26DDDA7D988547B56FBC007491:FG=1; ZFY=YlAwfOaBfcP52N:AR2NYPavFtVsbTy8X5ubtZIMWNoqM:C; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1686816274,1686912230,1687238103; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1687238991; ab_sr=1.0.1_ZjFiNjI5YWYyMzkzMjkyNzA1YjkzY2Q0NDdjYjc5MGU3Mzg1NTExNzczODA1YzliOWJlMjhhMzE0NjM0MTY0YjVmNGMxOWM3MTRkYmRjMDBiZGFmZTgwNTNhZGI5OTdlNzFiN2M2ZWIxOTEyZWY2NWEwM2ZiZGE5NzA3YzVmOTYzYjZjNTc4ZWNhZGJmMTA0NDFlNjc5MTJiMzkxMTg0OQ==',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    }
    # 发送 post 请求,传递数据字典 dic
    res = requests.post(url, data=dic, headers=headers)
    # 输出结果
    print(res.json()['trans_result']['data'][0]['dst'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    # JsReverse.py
    # 安装方法:pip install PyExecJs -i https://pypi.tuna.tsinghua.edu.cn/simple
    import execjs # 用于执行 JavaScript 代码的库
    
    # 定义函数
    def get_js(js_path, fuc_name, func_args):
        '''
        :param js_path:  js代码的文件路径
        :param fuc_name: 调用的js函数名称
        :param func_args: 传入的参数
        :return:
        '''
        # 1. 读取 js 代码
        with open(js_path, 'r', encoding='utf-8') as f:
            js_code = f.read()
    
        # 2. 编译 js 代码
        cjs = execjs.compile(js_code)
    
        # 3. 执行 js 代码,函数后面跟上一个参数
        # print(fuc_name, func_args)
        return cjs.call(fuc_name, func_args)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    注意

    *func_args 和 func_args

    *func_args:可变长度参数,接收的数据类型是元组,return cjs.call(fuc_name, func_args) 返回值时需要拆解,循环遍历取值

    func_args:只有一个参数时不用加 *

    // baidu.js
    var r = null
    function n(t, e) {
        for (var n = 0; n < e.length - 2; n += 3) {
            var r = e.charAt(n + 2);
            r = "a" <= r ? r.charCodeAt(0) - 87 : Number(r),
            r = "+" === e.charAt(n + 1) ? t >>> r : t << r,
            t = "+" === e.charAt(n) ? t + r & 4294967295 : t ^ r
        }
        return t
    }
    function w(t) {
        var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
        if (null === i) {
            var a = t.length;
            a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))
        } else {
            for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, l = s.length, u = []; c < l; c++)
                "" !== s[c] && u.push.apply(u, function(t) {
                    if (Array.isArray(t))
                        return e(t)
                }(o = s[c].split("")) || function(t) {
                    if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])
                        return Array.from(t)
                }(o) || function(t, n) {
                    if (t) {
                        if ("string" == typeof t)
                            return e(t, n);
                        var r = Object.prototype.toString.call(t).slice(8, -1);
                        return "Object" === r && t.constructor && (r = t.constructor.name),
                        "Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0
                    }
                }(o) || function() {
                    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
                }()),
                c !== l - 1 && u.push(i[c]);
            var p = u.length;
            p > 30 && (t = u.slice(0, 10).join("") + u.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + u.slice(-10).join(""))
        }
        for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = '320305.131321201' || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
            var _ = t.charCodeAt(v);
            _ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),
            g[y++] = _ >> 18 | 240,
            g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,
            g[y++] = _ >> 6 & 63 | 128),
            g[y++] = 63 & _ | 128)
        }
        for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)
            b = n(b += g[x], w);
        return b = n(b, k),
        (b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
        "".concat((b %= 1e6).toString(), ".").concat(b ^ f)
    }
    // 定义了一个函数,传递的参数是需要翻译的内容
    function b(e){
        // 返回数据
        return {
            from: 'en',
            to: 'zh',
            query: e,
            transtype: 'realtime',
            simple_means_flag: 3,
            sign: w(e),
            token: 'e1aca5af9de730135e0dba1cea1af143',
            domain: 'common',
            ts: +new Date
        }
    }
    console.log(b('hello'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    28、通过 Python 调用 Js代码的结果时,会出现如下错误

    在这里插入图片描述

    解决方案

    找到 Python 的安装目录下的 Lib 里的 subprocess.py 文件,将 encoding=None 改为 encoding=‘utf-8’

    在这里插入图片描述

    在这里插入图片描述

    记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~

  • 相关阅读:
    如何制定有效的项目进度计划——甘特图
    超图iServer rest服务之最佳路径分析
    图像相关知识(分辨率、帧率、数据格式、数据量以及像素时钟)
    中英文说明书丨TRC D-阿卓糖(D-Altrose)
    VUE3与Uniapp 二 (响应式变量ref)
    IE浏览器设置兼容性、清除缓存,重置浏览器、Edge浏览器设置兼容性
    七天入门node.js(04)
    联邦学习:按混合分布划分Non-IID样本
    Wordpress plugin removes ‘/category‘
    【LeetCode】219. 存在重复元素 II
  • 原文地址:https://blog.csdn.net/muyuhen/article/details/133001918