爬虫 — 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 // 时间戳

多抓几个包看数据变化

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

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

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

爬虫 — Js 逆向案例一英汉互译_第1张图片

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

爬虫 — Js 逆向案例一英汉互译_第2张图片

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

爬虫 — Js 逆向案例一英汉互译_第3张图片

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

爬虫 — Js 逆向案例一英汉互译_第4张图片

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

爬虫 — Js 逆向案例一英汉互译_第5张图片

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'))

9、运行后报错

        transtype: i,
                   ^

ReferenceError: i is not defined

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

爬虫 — Js 逆向案例一英汉互译_第6张图片

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'))

12、运行后报错

        sign: w(e),
              ^

ReferenceError: w is not defined

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

爬虫 — Js 逆向案例一英汉互译_第7张图片

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

爬虫 — Js 逆向案例一英汉互译_第8张图片

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'))

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

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

// baidu.js
var r = null

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

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

爬虫 — Js 逆向案例一英汉互译_第9张图片

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

方式一:

鼠标悬停显示

爬虫 — Js 逆向案例一英汉互译_第10张图片

方式二:

在控制台打印

爬虫 — Js 逆向案例一英汉互译_第11张图片

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'))

22、运行后报错

        b = n(b += g[x], w);
        ^

ReferenceError: n is not defined

23、找到函数 n 的来源

爬虫 — Js 逆向案例一英汉互译_第12张图片

24、复制函数 n 的代码

爬虫 — Js 逆向案例一英汉互译_第13张图片

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'))

26、运行后返回结果

{
  from: 'en',
  to: 'zh',
  query: 'hello',
  transtype: 'realtime',
  simple_means_flag: 3,
  sign: '54706.276099',
  token: 'e1aca5af9de730135e0dba1cea1af143',
  domain: 'common',
  ts: 1687239404824
}

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'])
# 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)

注意

*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'))

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

爬虫 — Js 逆向案例一英汉互译_第14张图片

解决方案

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

爬虫 — Js 逆向案例一英汉互译_第15张图片

爬虫 — Js 逆向案例一英汉互译_第16张图片

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

你可能感兴趣的:(爬虫,爬虫,python,javascript)