PyexecJS使用报错

先说成功的示例:
js部分:

function add(x, y) {
    return x + y
}

.py文件调用js

import execjs
# 运行环境
print(execjs.get().name)
# 返回值:Node.js(V8)

# 简单示例:
with open('add.js') as file:
    js_function = file.read()

ctx = execjs.compile(js_function)
x = 2
y = 8
print(ctx.call('add', x, y))
# 成功返回:10

出错的代码:

function _linik(params) {
    let dCode = atob(params);
    return decodeURI(dCode)
}

let params = 'aHR0cHM6Ly9kb3dubG9h'

console.log(_linik(params))

如果是直接运行上面这个js文件是成功执行的
但是如果用py文件调用就出错

调用出错的完整代码为:
js部分:


function _linik(params) {
    let dCode = atob(params);
    return decodeURI(dCode)
}

py部分:


import execjs
params = 'aHR0cHM6Ly9kb3dubG9h'

with open('get_link.js') as file:
    jscode = file.read()
ctx = execjs.compile(jscode)

ctx.call('_linik', params)

经过打印发现 就是这个call报错了

以下是报错内容:

Node.js (V8)
10
function _linik(params) {
    let dCode = atob(params);
    return decodeURI(dCode)
}

let params = 'aHR0cHM6Ly9kb3dubG9hZC1wcm8uY2pqZDIwLmNvbS8xMjMtNTU3LzY1M2UzMWQxLzE2NzU3MzItMC82NTNlMzFkMThiNjAwNjI3YjVkN2IxNTMzM2U3ODIyZD92PTImdD0xNjc0MjA2NjI5JnM9ZjkxMzU2NjVlMGM4ZWE5NGVhMTEzNTVjMzg3ZWI1ZjYmZmlsZW5hbWU9V2luJUU3JTg5JTg4K1BTKzIwMjIucmFy'

console.log(_linik(params))
_external_runtime.ExternalRuntime.Context object at 0x000002D8552B92D0>
Exception in thread Thread-3 (_readerthread):
Traceback (most recent call last):
  File "D:\Program Files\Python\Python311\Lib\threading.py", line 1038, in _bootstrap_inner
    self.run()
  File "D:\Program Files\Python\Python311\Lib\threading.py", line 975, in run
    self._target(*self._args, **self._kwargs)
  File "D:\Program Files\Python\Python311\Lib\subprocess.py", line 1552, in _readerthread
    buffer.append(fh.read())
                  ^^^^^^^^^
UnicodeDecodeError: 'gbk' codec can't decode byte 0x88 in position 158: illegal multibyte sequence
Traceback (most recent call last):
  File "D:\farml\PycharmProjects\django_farmllar\Apps\BaiduYunPan\tests.py", line 40, in 
    ctx.call('linik', params)
  File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_abstract_runtime_context.py", line 37, in call
    return self._call(name, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_external_runtime.py", line 92, in _call
    return self._eval("{identifier}.apply(this, {args})".format(identifier=identifier, args=args))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_external_runtime.py", line 78, in _eval
    return self.exec_(code)
           ^^^^^^^^^^^^^^^^
  File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_abstract_runtime_context.py", line 18, in exec_
    return self._exec_(source)
           ^^^^^^^^^^^^^^^^^^^
  File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_external_runtime.py", line 88, in _exec_
    return self._extract_result(output)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_external_runtime.py", line 156, in _extract_result
    output = output.replace("\r\n", "\n").replace("\r", "\n")
             ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'replace'

这个错误是由于 atob 和 decodeURI 两个函数是 JavaScript 的内置函数,在 Node.js 中可以正常使用,但是在 execjs 模块中不能使用。

解决方法有两种:

使用 JavaScript 的第三方库,如 "js-base64",在 js 文件中导入,然后替换 atob 和 decodeURI 两个函数。
在 Python 中手动实现 atob 和 decodeURI 函数,然后在 js 代码中使用这两个 Python 函数。
还有一点是提醒你阅读错误信息,在报错信息中可以看到是UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 2: illegal multibyte sequence,这是因为你的文件编码是gbk,而你的python环境编码是utf-8,所以会产生编码错误。可以在读取文件时加上编码格式'utf-8'。

根据你的错误提示,是编码的问题。进入subprocess.py文件修改,将encoding=None修改为encoding=‘utf-8’
参考:https://baijiahao.baidu.com/s?id=1745903738695011227&wfr=spider&for=pc&searchword=%E8%B0%83%E7%94%A8js%E6%96%87%E4%BB%B6%E6%8A%A5%E9%94%99gbk%20codec%20can%27t%20decode%20byte%200x88
望采纳!!!