PyExecJS是什么?

PyExecJS用于实现在Python中运行JavaScript代码的功能,移植自Ruby的ExecJS库。

该库自2018年以来已经停止维护(目前更好的库为js2py),但我们仍然可以用它在Python中解决一些JavaScript代码的运行问题。

PyExecJS库适合在能够获得完整的JavaScript函数代码的情况下使用,具体请继续阅读下面的案例。

安装:

pip install PyExecJS

代码案例

网页中有一些经过JavaScript代码加密的邮箱地址,通过让Python运行JavaScript文件里的解密函数实现解密,从而获取真实的邮箱地址。

代码中的js_code变量就是在JavaScript代码里面找到解密的函数,decryptString用来解密邮箱地址,decryptCharcode会被decryptString调用,所以把它们一起保留下来。

import execjs

# 获取当前电脑安装的js环境,没有的话,可以安装node.js解决
js_env = execjs.get()

# 网页里找到的js解密代码
js_code = """
    function decryptCharcode(n,start,end,offset) {
        n = n + offset;
        if (offset > 0 && n > end) {
            n = start + (n - end - 1);
        } else if (offset < 0 && n < start) {
            n = end - (start - n - 1);
        }
        return String.fromCharCode(n);
    }

    function decryptString(enc,offset) {
        var dec = "";
        var len = enc.length;
        for(var i=0; i < len; i++) {
            var n = enc.charCodeAt(i);
            if (n >= 0x2B && n <= 0x3A) {
                dec += decryptCharcode(n,0x2B,0x3A,offset); // 0-9 . , - + / :
            } else if (n >= 0x40 && n <= 0x5A) {
                dec += decryptCharcode(n,0x40,0x5A,offset); // A-Z @
            } else if (n >= 0x61 && n <= 0x7A) {
                dec += decryptCharcode(n,0x61,0x7A,offset); // a-z
            } else {
                dec += enc.charAt(i);
            }
        }
        return dec;
    }
"""

# 编译js解密代码
js_compiled = js_env.compile(js_code)

# encoded_mail是经过加密的邮箱地址,作为参数传给解密函数decryptString
js_func = 'decryptString('"{}"', 2)'.format(encoded_mail)

# 得到最终结果
result_email = js_compiled.eval(js_func)