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