Bootstrap

execjs的学习

execjs的学习

1.基本使用
pip install pyExecJs #安装模块
apt-get install nodejs # execjs模块基于node运行的,(此方式是在Linux中使用 windows请安装node包)


import execjs
js="""
// 函数
function getnow(){
    var timestamp=new Date().getTime();
    return timestamp;
}
// 变量
var name="12353454";
"""

# 通过compile命令转成一个js对象
execjs.compile(js) #第二个参数cwd可以传入环境
# 调用function方法
res = docjs.call('getnow')
print(res)
# 调用变量方法
res = docjs.eval('name')
print(res)

2.记一次错误调用解决

import execjs

def generate_visitor_id():
    js = '''
         const jsdom = require("jsdom");
         const { JSDOM } = jsdom;
         const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
         window = dom.window;
         document = window.document;
         function r()
         {
             function t()
             {
                 return n?15&n[e++]:16*Math.random()|0
             }
             var n=null,e=0,r=window.crypto||window.msCrypto;
             r&&r.getRandomValues&&(n=r.getRandomValues(new Uint8Array(31)));
             for(var o,i="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",a="",s=0;s<i.length;s++)
                 o=i[s],"x"===o?a+=t().toString(16):"y"===o?(o=3&t()|8,a+=o.toString(16)):a+=o;
             return a
         }
     '''
    
    p = execjs.compile(js)
    return p.call('r')

if __name__ == '__main__':
    vid = generate_visitor_id()
    print(vid)
    
2.记一次分析js
事故1:

python运行execjs中出现编码问题

报错如下

“”"
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x80 in position 41: illegal multibyte sequence
“”"
解决方法:

原因是有一个程序在使用TextIOWrapper 类创建对象时默认使用了cp936的编码,也就是gbk编码,读取不了utf-8的字符,
所以我们可以修改下 subprocess.py 文件的默认编码方式为utf-8即可在代码行656有个初始化,直接修改默认即可,如下

在这里插入图片描述

事故2:

报错如下:

execjs._exceptions.ProgramError: Error: Cannot find module ‘jsdom’

因为在node里也是只能运行js语法,window 和 document等对象是没有的但是node有个库jsdom可以生成对应环境

https://www.npmjs.com/package/jsdom

解决方案如下:

全局安装命令
npm i jsdom -g

然后js中写入
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
window = dom.window;
document = window.document;
放入运行函数


在全局安装jsdom后,在node里按上面的写法是没有问题的,但是我们要在python中使用的话,不能在全局安装
如果在全局安装,使用时会报如下错误,说找不到jsdom
execjs._exceptions.ProgramError: Error: Cannot find module 'jsdom'
解决办法有两种
1.就是在python执行文件所在的运行目录下,使用npm安装jsdom
2. 使用cwd参数,指定模块的所在目录,比如,我们在全局安装的jsdom,在cmd里通过npm root -g 可以查看全局模块安装路径: C:\Users\Lenovo\AppData\Local\node-v12.16.1-win-x64\node-global\node_modules

完整代码如下
import execjs

def generate_visitor_id():
    js = '''
         const jsdom = require("jsdom");
         const { JSDOM } = jsdom;
         const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
         window = dom.window;
         document = window.document;
         function r()
         {
             function t()
             {
                 return n?15&n[e++]:16*Math.random()|0
             }
             var n=null,e=0,r=window.crypto||window.msCrypto;
             r&&r.getRandomValues&&(n=r.getRandomValues(new Uint8Array(31)));
             for(var o,i="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",a="",s=0;s<i.length;s++)
                 o=i[s],"x"===o?a+=t().toString(16):"y"===o?(o=3&t()|8,a+=o.toString(16)):a+=o;
             return a
         }
     '''
    p = execjs.compile(js,cwd=r"C:\Users\Lenovo\AppData\Local\node-v12.16.1-win-x64\node-global\node_modules")
    return p.call('r')

if __name__ == '__main__':
    vid = generate_visitor_id()
    print(vid)

参考链接:

https://www.cnblogs.com/huchong/p/11044238.html

https://blog.csdn.net/qq_37619987/article/details/104184340

;