python基础之调用JS函数

调用方式一:execjs

安装execjs: pip install PyExecJS 

1. 以字符串方式调用

call_js.py

import execjs
js_function = """
function s(j,r){var a=[];var p=[];var o="";var v=j.length;for(var q=0;q<256;q++){a[q]=j.substr((q%v),1).charCodeAt(0);p[q]=q}for(var u=q=0;q<256;q++){u=(u+p[q]+a[q])%256;var t=p[q];p[q]=p[u];p[u]=t}for(var i=u=q=0;q<r.length;q++){i=(i+1)%256;u=(u+p[i])%256;var t=p[i];p[i]=p[u];p[u]=t;k=p[((p[i]+p[u])%256)];o+=String.fromCharCode(r.charCodeAt(q)^k)}return o};
"""
encode_value = execjs.compile(js_function).call("s", r, l)
print(encode_value)

2. 以文本方式调用

js_function.js

function s(j, r) {
    var a = [];
    var p = [];
    var o = "";
    var v = j.length;
    for (var q = 0; q < 256; q++) {
        a[q] = j.substr((q % v), 1).charCodeAt(0);
        p[q] = q
    }
    for (var u = q = 0; q < 256; q++) {
        u = (u + p[q] + a[q]) % 256;
        var t = p[q];
        p[q] = p[u];
        p[u] = t
    }
    for (var i = u = q = 0; q < r.length; q++) {
        i = (i + 1) % 256;
        u = (u + p[i]) % 256;
        var t = p[i];
        p[i] = p[u];
        p[u] = t;
        k = p[((p[i] + p[u]) % 256)];
        o += String.fromCharCode(r.charCodeAt(q) ^ k)
    }
    return o
}
View Code

call_js.py

import execjs

def _get_runntime():
    phantom = execjs.get()
    with open('js_function.js', 'r') as f:
        source = f.read()
    return phantom.compile(source)

encode_value = _get_runntime().call('s', r, l)
print(encode_value)

调用方式2:js2py

安装js2py: pip install js2py 

call_js.py

import js2py

js_function = """
function s(j,r){var a=[];var p=[];var o="";var v=j.length;for(var q=0;q<256;q++){a[q]=j.substr((q%v),1).charCodeAt(0);p[q]=q}for(var u=q=0;q<256;q++){u=(u+p[q]+a[q])%256;var t=p[q];p[q]=p[u];p[u]=t}for(var i=u=q=0;q<r.length;q++){i=(i+1)%256;u=(u+p[i])%256;var t=p[i];p[i]=p[u];p[u]=t;k=p[((p[i]+p[u])%256)];o+=String.fromCharCode(r.charCodeAt(q)^k)}return o};
"""

encode_value = js2py.eval_js(js_function)(r, l)
print(encode_value)

对这两个方式目前还存在一点疑惑没解决

call_js.py

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
"""=================================================
@Project -> File    : call_js.py
@IDE     : PyCharm
@Author  : zihan
@Date    : 2022/1/3 9:53
@Desc    :
================================================="""
import execjs
import js2py


js_function = """
function s(j,r){var a=[];var p=[];var o="";var v=j.length;for(var q=0;q<256;q++){a[q]=j.substr((q%v),1).charCodeAt(0);p[q]=q}for(var u=q=0;q<256;q++){u=(u+p[q]+a[q])%256;var t=p[q];p[q]=p[u];p[u]=t}for(var i=u=q=0;q<r.length;q++){i=(i+1)%256;u=(u+p[i])%256;var t=p[i];p[i]=p[u];p[u]=t;k=p[((p[i]+p[u])%256)];o+=String.fromCharCode(r.charCodeAt(q)^k)}return o};
"""


def _get_runntime():
    phantom = execjs.get()  
    with open('js_function.js', 'r') as f:
        source = f.read()
    return phantom.compile(source)


def get_s(r, l):
    encode_value = _get_runntime().call('s', r, l)
    print(encode_value)
    encode_value = execjs.compile(js_function).call("s", r, l)
    print(encode_value)
    encode_value = js2py.eval_js(js_function)(r, l)
    print(encode_value)
    #want: encode_value = 'ú\x1FBoÁ\n\x1Fn¢\x0Fa\x1EQ\x01\x92òVx¯o¤h9Õ%G¶\x89ÄQâ*7EÁö.\x7FÒÓ'
    return _get_runntime().call('base64Encode', encode_value)


def main():
    # sign3
    f = 'e8c7d729eea7b54551aa594f942decbe'
    # sign1
    l = '84dcadc608ddd0d635e81b35821a0a3a7b7e31b4'
    sign = get_s(f, l)
    # want: +h9Cb8EKH26iD2EeUQGS8lZ4r2+kaDnVJUe2icRR4io3RcH2Ln/S0w==
    print(sign)


if __name__ == '__main__':
    main()
View Code

运行结果

煤Bo脕
n垄aQ聮貌Vx炉o陇h9脮%G露聣脛Q芒*7E脕枚.脪脫
煤Bo脕
n垄aQ聮貌Vx炉o陇h9脮%G露聣脛Q芒*7E脕枚.脪脫
úBoÁ
n¢aQ’òVx¯o¤h9Õ%G¶‰ÄQâ*7EÁö.ÒÓ
+h9Cb8EKH26iD2EeUQGS8lZ4r2+kaDnVJUe2icRR4io3RcH2Ln/S0w==
View Code

可以看到使用js2py和execjs运行同一个函数的结果并不相同,当前状态是js2py得到的结果是想要的,不过目前并不清楚其中的区别,可能得继续研究。

进一步研究发现,原来之前电脑安装了Node.js,导致execjs的默认JS环境变成了Node.js (V8),默认Windows下的JS环境是JScript。所以只需要在get时指定execjs的环境为Windows默认环境就行了。

call_js.py

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
"""=================================================
@Project -> File    : call_js.py
@IDE     : PyCharm
@Author  : zihan
@Date    : 2022/1/3 9:53
@Desc    :
================================================="""
import execjs
import js2py


js_function = """
function s(j,r){var a=[];var p=[];var o="";var v=j.length;for(var q=0;q<256;q++){a[q]=j.substr((q%v),1).charCodeAt(0);p[q]=q}for(var u=q=0;q<256;q++){u=(u+p[q]+a[q])%256;var t=p[q];p[q]=p[u];p[u]=t}for(var i=u=q=0;q<r.length;q++){i=(i+1)%256;u=(u+p[i])%256;var t=p[i];p[i]=p[u];p[u]=t;k=p[((p[i]+p[u])%256)];o+=String.fromCharCode(r.charCodeAt(q)^k)}return o};
"""


def _get_runntime():
    phantom = execjs.get()
    print(phantom.name)
    phantom = execjs.get(execjs.runtime_names.JScript)
    print(phantom.name)
    with open('js_function.js', 'r') as f:
        source = f.read()
    return phantom.compile(source)


def get_s(r, l):
    encode_value = _get_runntime().call('s', r, l)
    print(encode_value)
    encode_value = execjs.get(execjs.runtime_names.JScript).compile(js_function).call("s", r, l)
    print(encode_value)
    # encode_value = js2py.eval_js(js_function)(r, l)
    # print(encode_value)
    #want: encode_value = 'ú\x1FBoÁ\n\x1Fn¢\x0Fa\x1EQ\x01\x92òVx¯o¤h9Õ%G¶\x89ÄQâ*7EÁö.\x7FÒÓ'
    return _get_runntime().call('base64Encode', encode_value)


def main():
    # sign3
    f = 'e8c7d729eea7b54551aa594f942decbe'
    # sign1
    l = '84dcadc608ddd0d635e81b35821a0a3a7b7e31b4'
    sign = get_s(f, l)
    # want: +h9Cb8EKH26iD2EeUQGS8lZ4r2+kaDnVJUe2icRR4io3RcH2Ln/S0w==
    print(sign)


if __name__ == '__main__':
    main()
View Code

主要变化代码是 execjs.get(execjs.runtime_names.JScript) 。至此,这个问题结束。

原文地址:https://www.cnblogs.com/smart-zihan/p/15759711.html